Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git c/Files w/Files
- index 9d40931..2d7e194 100644
- --- c/Files
- +++ w/Files
- @@ -38,7 +38,7 @@ endgame.des engrave.txt epitaph.txt gehennom.des help
- hh history keyhelp knox.des license
- medusa.des mines.des opthelp oracle.des oracles.txt
- quest.txt rumors.fal rumors.tru sokoban.des symbols
- -tower.des tribute wizhelp yendor.des
- +tower.des tribute wizhelp yendor.des Infidel.des
- doc:
- (files for all versions)
- diff --git c/dat/Infidel.des w/dat/Infidel.des
- new file mode 100644
- index 0000000..df7502e
- --- /dev/null
- +++ w/dat/Infidel.des
- @@ -0,0 +1,385 @@
- +# The "start" level for the quest.
- +#
- +# Here you meet your class leader, the preacher of Moloch,
- +# and receive an invitation to a duel with the Paladin.
- +#
- +MAZE: "Inf-strt", ' '
- +FLAGS: noteleport, hardfloor
- +GEOMETRY: right, center
- +# 1 2 3 4 5 6
- +#01234567890123456789012345678901234567890123456789012345678901
- +MAP
- +0 |.........................
- +1 |.........................
- +2 ----- --........................
- +3 ---- ---...----- --........................
- +4 |..| --.........| |.........................
- +5 |..| |..........| --.........................
- +6 -+-- ---..........---- |..........................
- +7 # ---...............| --.........................
- +8 # |.................--- |.........................
- +9 ---S- ---...................| |-........................
- +0 |...| |.....................+####S.........................
- +1 |...+###+.....................| |.........................
- +2 |...| |....................-- |.........................
- +3 ----- ----.................| --.........................
- +4 |.................| |..........................
- +5 ---- ##S...............--- --..........................
- +6 |..| # ---............-- |...........................
- +7 |..+## |........----- --..........................
- +8 |..| ---------- |..........................
- +9 |..| |-.........................
- +0 ---- |..........................
- +ENDMAP
- +NON_DIGGABLE: (00, 00, 37, 20)
- +
- +# You arrive at a sparsely wooded cliffside.
- +REPLACE_TERRAIN: (35, 00, 61, 20), '.', 'T', 1%
- +BRANCH: (38, 00, 61, 20), (00, 00, 00, 00)
- +$outside = selection: filter('.', fillrect(35, 00, 61, 20))
- +LOOP [3d4] { MONSTER: 'd', rndcoord($outside) }
- +[20%]: MONSTER: "black unicorn", rndcoord($outside)
- +TRAP: random, rndcoord($outside)
- +TRAP: random, rndcoord($outside)
- +TRAP: random, rndcoord($outside)
- +
- +# The Hidden Temple is behind a secret door.
- +# The altar is coaligned, but haunted,
- +# presumably having been forcibly converted in the past.
- +TRAP: "dart", (37, 10)
- +DOOR: locked, (31, 10)
- +REGION: (20, 10, 20, 10), lit, "temple", irregular
- +ALTAR: (20, 10), coaligned, altar
- +MONSTER: "preacher of Moloch", (20, 10)
- +MONSTER: "cultist", (20, 07)
- +MONSTER: "cultist", (23, 08)
- +MONSTER: "cultist", (24, 10)
- +MONSTER: "cultist", (23, 12)
- +MONSTER: "cultist", (20, 13)
- +MONSTER: "cultist", (17, 12)
- +MONSTER: "cultist", (16, 10)
- +MONSTER: "cultist", (17, 08)
- +
- +# Some "decorations".
- +$around_altar = selection: ellipse((20, 10), 4, 3)
- +OBJECT: "corpse", montype: "elf", rndcoord($around_altar)
- +OBJECT: "corpse", montype: "elf", rndcoord($around_altar)
- +OBJECT: "corpse", montype: "elf", rndcoord($around_altar)
- +OBJECT: "corpse", montype: "human", rndcoord($around_altar)
- +OBJECT: "corpse", montype: "human", rndcoord($around_altar)
- +$statues = { (20, 04), (24, 05), (27, 08), (28, 13),
- + (25, 15), (19, 16), (14, 14), (13, 09) }
- +SHUFFLE: $statues
- +CONTAINER: "statue", montype: "horned devil", $statues[0] {}
- +CONTAINER: "statue", montype: "barbed devil", $statues[1] {}
- +CONTAINER: "statue", montype: "marilith", $statues[2] {}
- +CONTAINER: "statue", montype: "vrock", $statues[3] {}
- +CONTAINER: "statue", montype: "hezrou", $statues[4] {}
- +CONTAINER: "statue", montype: "bone devil", $statues[5] {}
- +CONTAINER: "statue", montype: "ice devil", $statues[6] {}
- +CONTAINER: "statue", montype: "pit fiend", $statues[7] {}
- +
- +# Entrance to the underground complex leading to the Howling Forest.
- +DOOR: closed, (09, 11)
- +DOOR: closed, (05, 11)
- +REGION: (02, 10, 04, 12), lit, "ordinary"
- +STAIR: (03, 11), down
- +
- +# Unholy water supply.
- +DOOR: locked, (04, 06)
- +REGION: (04, 04, 05, 05), lit, "ordinary"
- +OBJECT: ('!', "water"), cursed, quantity: 1d2, (04, 04)
- +OBJECT: ('!', "water"), cursed, quantity: 1d2, (05, 04)
- +
- +# A small cache of valuables.
- +DOOR: locked, (08, 17)
- +REGION: (06, 16, 07, 19), lit, "ordinary"
- +OBJECT: random, (06, 16)
- +OBJECT: random, (06, 17)
- +OBJECT: "axe", (06, 18)
- +OBJECT: random, (06, 19)
- +
- +#
- +# The "locate" level for the quest.
- +#
- +# This is the edge of the Howling Forest.
- +# Somewhere in here the Paladin awaits you.
- +
- +MAZE: "Inf-loca", ' '
- +FLAGS: hardfloor
- +INIT_MAP: mines, '.', 'T', true, true, unlit, true
- +GEOMETRY: (49, 00)
- +# 1 2
- +#12345678901234567890123456789
- +MAP
- +xxxx.| ---- 0
- +xxx..-- |..| 1
- +x.....--- |..| 2
- +...}}...| -+-- 3
- +...}}}..-- # 4
- +..}}}....| # 5
- +...}}....| --S- 6
- +.........-- |..| 7
- +..........-- |..| 8
- +...........| |..+#### 9
- +...........+#####+..| # 0
- +...........| |..| # 1
- +...........| ---- # 2
- +..........-- # 3
- +.........-- # 4
- +.........| # 5
- +........-| --+-- 6
- +.........| |...| 7
- +x......--- |...| 8
- +xxx.---- ----- 9
- +xxxx| 0
- +ENDMAP
- +NON_DIGGABLE: (05, 00, 29, 20)
- +
- +# Upstairs to (rest of) the underground complex.
- +REGION: (23, 17, 25, 18), random, "ordinary"
- +STAIR: (24, 18), up
- +MONSTER: 'k', rndcoord(fillrect(23, 17, 25, 18))
- +DOOR: random, (24, 16)
- +
- +# The last room before the Forest!
- +DOOR: random, (20, 09)
- +REGION: (18, 07, 19, 11), random, "ordinary"
- +MONSTER: 'h', rndcoord(fillrect(18, 07, 19, 11))
- +DOOR: random, (17, 10)
- +DOOR: random, (11, 10)
- +
- +# An ogre guards some treasure.
- +DOOR: locked, (19, 03)
- +REGION: (19, 01, 20, 02), random, "ordinary"
- +MONSTER: 'O', (19, 02)
- +OBJECT: "chest", (19, 01)
- +OBJECT: "chest", (20, 01)
- +
- +# The lake.
- +MONSTER: "piranha", (03, 03)
- +MONSTER: "piranha", (04, 04)
- +MONSTER: "piranha", (04, 05)
- +
- +# The forest's edge.
- +REPLACE_TERRAIN: (00, 00, 10, 20), '.', 'T', 5%
- +NOMAP
- +STAIR: (00, 00, 39, 20), (0, 0, 0, 0), down
- +$forest = selection: filter('.', fillrect(00, 00, 60, 20))
- +MONSTER: "werewolf", rndcoord($forest)
- +MONSTER: "werewolf", rndcoord($forest)
- +MONSTER: "werewolf", rndcoord($forest)
- +LOOP [4d4] { MONSTER: 'd', rndcoord($forest) }
- +MONSTER: 'u', rndcoord($forest)
- +MONSTER: 'u', rndcoord($forest)
- +[65%]: MONSTER: "forest centaur", rndcoord($forest)
- +[40%]: MONSTER: "woodchuck", rndcoord($forest)
- +
- +# Some traps and a little loot.
- +OBJECT: random, random
- +OBJECT: random, random
- +OBJECT: random, random
- +OBJECT: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +
- +#
- +# The "goal" level for the quest.
- +#
- +# In this part of the Howling Forest the Paladin awaits you for a duel
- +# amidst some ancient ruins. Kill her to claim the Idol of Moloch!
- +#
- +# Note: some may find the Paladin a tough opponent. It's intentional!
- +# You come here to duel her at HER behest, on HER conditions.
- +# She expects to defeat you and came prepared. To win, you need to
- +# outwit her.
- +#
- +
- +MAZE: "Inf-goal", ' '
- +FLAGS: hardfloor
- +INIT_MAP: mines, '.', 'T', true, true, unlit, true
- +GEOMETRY: half-left, center
- +# 1 2
- +#0123456789012345678901234567
- +MAP
- +0xxxxxxxxxx........xxxxxxxxxx
- +1xxxxxxx..............xxxxxxx
- +2xxxx....................xxxx
- +3xx........--..-...........xx
- +4x.........|.....|..........x
- +5.............--.|...........
- +6x........--................x
- +7xx........|..|...--.......xx
- +8xxxx.........|..........xxxx
- +9xxxxxxx..............xxxxxxx
- +0xxxxxxxxxx........xxxxxxxxxx
- +ENDMAP
- +
- +# The Paladin and her entourage.
- +MONSTER: "Paladin", (13, 06)
- +OBJECT: "figurine", name: "The Idol of Moloch", cursed, (13, 06)
- +MONSTER: "templar", (13, 03), asleep
- +MONSTER: "templar", (15, 04), asleep
- +MONSTER: "templar", (17, 06), asleep
- +MONSTER: "aligned priest", (16, 08), law, hostile, asleep
- +MONSTER: "templar", (13, 09), asleep
- +MONSTER: "templar", (10, 08), asleep
- +MONSTER: "templar", (09, 05), asleep
- +MONSTER: "aligned priest", (11, 04), law, hostile, asleep
- +
- +# Just pretend they're tripwires.
- +$around = selection: filter('.', filter(ellipse((13, 05), 9, 5),
- + complement(ellipse((13, 05), 4, 3))))
- +TRAP: "board", rndcoord($around)
- +TRAP: "board", rndcoord($around)
- +TRAP: "board", rndcoord($around)
- +TRAP: "board", rndcoord($around)
- +
- +# There's still some treasure buried in the ruins.
- +$ruins = selection: circle((13, 06), 4)
- +OBJECT: "gold piece", quantity: 10d100, buried, rndcoord($ruins)
- +OBJECT: "gold piece", quantity: 10d100, buried, rndcoord($ruins)
- +OBJECT: '*', buried, rndcoord($ruins)
- +OBJECT: '*', buried, rndcoord($ruins)
- +OBJECT: '*', buried, rndcoord($ruins)
- +[60%]: OBJECT: '=', buried, rndcoord($ruins)
- +[50%]: OBJECT: '=', buried, rndcoord($ruins)
- +[40%]: OBJECT: '"', buried, rndcoord($ruins)
- +
- +# The surrounding woods.
- +NOMAP
- +STAIR: (45, 0, 79, 20), (0, 0, 0, 0), up
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +LOOP [5d4] { MONSTER: 'd', random }
- +MONSTER: 'u', random
- +MONSTER: 'u', random
- +MONSTER: 'u', random
- +[80%]: MONSTER: "forest centaur", random
- +[50%]: MONSTER: "woodchuck", random
- +
- +# And a bit of random junk.
- +OBJECT: random, random
- +OBJECT: random, random
- +OBJECT: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +
- +#
- +# The "fill" levels for the quest.
- +#
- +# These levels are used to fill out any levels not occupied by specific
- +# levels as defined above. "fila" is the upper filler, between the
- +# start and locate levels, and "filb" the lower between the locate
- +# and goal levels.
- +#
- +# The upper filler is the underground complex that leads to the Forest.
- +# It's a standard room-and-corridor dungeon populated with hkO.
- +#
- +
- +LEVEL: "Inf-fila"
- +FLAGS: hardfloor
- +
- +ROOM: "ordinary", random, random, random, random {
- + STAIR: random, up
- + OBJECT: random, random
- + MONSTER: 'k', random
- +}
- +
- +ROOM: "ordinary", random, random, random, random {
- + STAIR: random, down
- + OBJECT: random, random
- + TRAP: random, random
- + MONSTER: 'h', random
- + MONSTER: 'k', random
- +}
- +
- +# Quest dungeons always seem so empty, so here's a fountain.
- +ROOM: "ordinary", random, random, random, random {
- + FOUNTAIN: random
- + OBJECT: random, random
- + MONSTER: 'h', random
- +}
- +
- +# Throne monsters roughly suit the hkO theme.
- +ROOM: "throne" [25%], random, random, random, random {
- + OBJECT: random, random
- + TRAP: random, random
- +}
- +
- +ROOM: "ordinary", random, random, random, random {
- + OBJECT: random, random
- + TRAP: random, random
- + MONSTER: 'k', random
- + MONSTER: 'k', random
- +}
- +
- +ROOM: "ordinary", random, random, random, random {
- + OBJECT: random, random
- + OBJECT: random, random
- + TRAP: random, random
- + TRAP: random, random
- + MONSTER: 'O', random
- + MONSTER: 'h', random
- +}
- +
- +ROOM: "ordinary", random, random, random, random {
- + OBJECT: random, random
- + OBJECT: random, random
- + TRAP: random, random
- + TRAP: random, random
- + MONSTER: 'O', random
- + MONSTER: 'k', random
- +}
- +
- +RANDOM_CORRIDORS
- +
- +#
- +# The lower fillers are some nondescript areas of the Howling Forest.
- +# There's a lot of werewolves and other d and perhaps a woodchuck.
- +#
- +
- +MAZE: "Inf-filb", ' '
- +FLAGS: hardfloor
- +INIT_MAP: mines, '.', 'T', true, true, unlit, true
- +NOMAP
- +
- +STAIR: (45, 00, 79, 20), (0, 0, 0, 0), up
- +STAIR: (00, 00, 34, 20), (0, 0, 0, 0), down
- +
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +MONSTER: "werewolf", random
- +LOOP [6d4] { MONSTER: 'd', random }
- +MONSTER: 'u', random
- +MONSTER: 'u', random
- +MONSTER: 'u', random
- +MONSTER: 'u', random
- +MONSTER: "forest centaur", random
- +[60%]: MONSTER: "woodchuck", random
- +
- +OBJECT: random, random
- +OBJECT: random, random
- +OBJECT: random, random
- +OBJECT: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- +TRAP: random, random
- diff --git c/dat/data.base w/dat/data.base
- index 4046259..0c1b1c2 100644
- --- c/dat/data.base
- +++ w/dat/data.base
- @@ -71,6 +71,16 @@ agate*
- solution is slowly deposited into cavities and veins in older
- rock.
- [ The Columbia Encyclopedia, Sixth Edition ]
- +agent
- +agent of *
- + It was part of his profession to kill people. He had never liked
- + doing it and when he had to kill he did it as well as he knew how
- + and forgot about it. As a secret agent who held the rare double-O
- + prefix -- the licence to kill in the Secret Service -- it was his
- + duty to be as cool about death as a surgeon. If it happened,
- + it happened. Regret was unprofessional -- worse, it was
- + death-watch beetle in the soul.
- + [ Goldfinger, by Ian Fleming ]
- aleax
- Said to be a doppelganger sent to inflict divine punishment
- for alignment violations.
- @@ -412,6 +422,8 @@ banshee
- [ Brewer's Concise Dictionary of Phrase and Fable ]
- barbarian
- * barbarian
- +champion
- +champion of *
- They dressed alike -- in buckskin boots, leathern breeks and
- deerskin shirts, with broad girdles that held axes and short
- swords; and they were all gaunt and scarred and hard-eyed;
- @@ -2436,6 +2448,11 @@ idefix
- strong views on the environment (he howls whenever he sees an
- uprooted tree).
- [ Wikipedia, the free encyclopedia ]
- +*idol of moloch
- + One of the rare few artifacts able to exert Moloch's influence
- + aboveground. By drawing on Moloch's power, the faithful are able
- + to summon demons, defile shrines, and replenish their magical
- + energy. The Idol also protects its holder from hostile magics.
- # takes "imp or minor demon" when specifying 'i'
- imp
- imp or minor demon
- @@ -2458,6 +2475,23 @@ succubus
- same demon, one who lies with a human for its own purposes,
- usually to the detriment of the mortals who are unwise in
- their dealings with them.
- +infidel
- +* infidel
- +cultist
- +malefic*
- + We must especially observe that this heresy, witchcraft, not only
- + differs from all other heresy in this, that not merely by a tacit
- + compact, but by a compact which is exactly defined and expressed
- + it blasphemes the Creator and endeavours to the utmost to profane Him
- + and to harm His creatures, for all other simple heresies have made
- + no open compact with the devil, no compact, that is, either tacit
- + or exactly expressed, although their errors and misbelief are directly
- + to be attributed to the Father of errors and lies. Moreover,
- + maleficium (witchcraft) differs from all other harmful and mysterious
- + arts in this point, that of all superstition it is essentially
- + the vilest, the most evil and the worst, wherefore it derives its name
- + from doing evil, and from blaspheming the true faith.
- + [ The Malleus Maleficarum, translated by Montague Summers ]
- *insect
- *insects
- A minute invertebrate animal; one of the class _Insecta_.
- @@ -3851,6 +3885,17 @@ page
- of gentle parentage attending a royal or princely personage.
- [ Webster's Comprehensive International Dictionary
- of the English Language ]
- +*paladin
- +*paladin of *
- + The paladin is a noble and heroic warrior, the symbol of all
- + that is right and true in the world. As such, he has high ideals
- + that he must maintain at all times. Throughout legend and history
- + there are many heroes who could be called paladins: Roland and
- + the 12 Peers of Charlemagne, Sir Lancelot, Sir Gawain, and Sir Galahad
- + are all examples of the class. However, many brave and
- + heroic soldiers have tried and failed to live up to the ideals of
- + the paladin. It is not an easy task!
- + [ AD&D Player's Handbook, 2nd Edition ]
- *pall
- _Pallium._ The Roman name for a square woollen cloak worn
- by men in ancient Greece, especially by philosophers and
- @@ -4588,6 +4633,14 @@ scroll *
- I read these words, and read again, and tried
- My eyes against the heavens, and read again.
- [ Endymion, by John Keats ]
- +secespita
- + The secespita is a long iron sacrificial knife, made of brass
- + and copper from Cyprus, with a solid and rounded ivory handle,
- + which is secured to the hilt by a ring of silver or gold.
- + The flamens and their wives, the flaminicae, who were priests
- + and priestesses of the Ancient Rome, the virgins and the pontiffs
- + made use of it for sacrifices.
- + [ Wikipedia, the free encyclopedia ]
- set
- seth
- The ancient Egyptian god of chaos (Set), the embodiment of
- @@ -4837,6 +4890,12 @@ javelin
- don't I?"
- "Why, yes, of course," said Wilbur.
- [ Charlotte's Web, by E.B. White ]
- +splanchomanc*
- +anthropomanc*
- + Anthropomancy is a method of divination by the entrails of dead
- + or dying men or women, often virgin female children, through
- + sacrifice. This practice was sometimes also called splanchomancy.
- + [ Wikipedia, the free encyclopedia ]
- *spore
- *sphere
- The attack by those who want to die -- this is the attack
- @@ -4981,6 +5040,20 @@ susano*o
- [ Encyclopedia of Gods, by Michael Jordan ]
- tanko
- Samurai plate armor of the Yamato period (AD 300 - 710).
- +templar
- +templar of *
- + Above all things, whosoever would be a knight of Christ,
- + choosing such holy orders, you in your profession of faith
- + must unite pure diligence and firm perseverence, which is so worthy
- + and so holy, and is known to be so noble, that if it is preserved
- + untainted for ever, you will deserve to keep company with the martyrs
- + who gave their souls for Jesus Christ. In this religious order
- + has flourished and is revitalised the order of knighthood. [...]
- + God works well with us and our saviour Jesus Christ; He has sent
- + his friends from the Holy City of Jerusalem to the marches of France
- + and Burgundy, who for our salvation and the spread of the true faith
- + do not cease to offer their souls to God, a welcome sacrifice.
- + [ Rule of the Knights Templar, translated by J. M. Upton-Ward ]
- tengu
- The tengu was the most troublesome creature of Japanese
- legend. Part bird and part man, with red beak for a nose
- diff --git c/dat/endgame.des w/dat/endgame.des
- index ebd9049..2e6b738 100644
- --- c/dat/endgame.des
- +++ w/dat/endgame.des
- @@ -479,7 +479,7 @@ MONSTER:('E',"water elemental"),random,hostile
- MAZE:"astral",' '
- FLAGS: noteleport,hardfloor,nommap,shortsighted,solidify
- MESSAGE: "You arrive on the Astral Plane!"
- -MESSAGE: "Here the High Temple of %d is located."
- +MESSAGE: "Here the High Temples of the heaven are located."
- MESSAGE: "You sense alarm, hostility, and excitement in the air!"
- GEOMETRY:center,center
- MAP
- diff --git c/dat/gehennom.des w/dat/gehennom.des
- index 65fab4e..fcd2be7 100644
- --- c/dat/gehennom.des
- +++ w/dat/gehennom.des
- @@ -75,6 +75,7 @@ NON_DIGGABLE:(00,00,75,19)
- # **LOTS** of dead bodies (all human).
- # note: no priest(esse)s or monks - maybe Moloch has a *special*
- # fate reserved for members of *those* classes.
- +# Obviously, no Infidel corpses as well.
- #
- OBJECT:('%',"corpse"),random,montype:"archeologist"
- OBJECT:('%',"corpse"),random,montype:"archeologist"
- diff --git c/dat/quest.txt w/dat/quest.txt
- index 269ec76..ef77f54 100644
- --- c/dat/quest.txt
- +++ w/dat/quest.txt
- @@ -10,7 +10,7 @@
- # QT_FIRSTTIME 1
- # QT_NEXTTIME 2
- # QT_OTHERTIME 3
- -#
- +# QT_ALTSTART 4 /* alternate game start message (optional) */
- # QT_GUARDTALK 5 /* 5 random things guards say before quest */
- # QT_GUARDTALK2 10 /* 5 random things guards say after quest */
- #
- @@ -41,6 +41,11 @@
- #
- # QT_GOTIT 70
- #
- +# /* For Infidels: Moloch's dialogue */
- +# QT_MOLOCH_1 71 /* offered Amulet, no Idol */
- +# QT_MOLOCH_2 72 /* offered Amulet, got Idol */
- +# QT_MOLOCH_3 73 /* high priest's altar hint */
- +#
- # QT_KILLEDNEM 80
- # QT_OFFEREDIT 81
- # QT_OFFEREDIT2 82 /* if you throw artifact to leader after #81 */
- @@ -1086,6 +1091,353 @@ to the Astral, and there return the Amulet to %d. Go forth and
- may our prayers be as a wind upon your back."
- %E ["You have recovered the Amulet. Travel to the Astral Plane and return it to %d."]
- #
- +# Infidel
- +#
- +%Cc Inf 00001
- +You arrive at the mouth of a cave that hosts %H. This is
- +the place where %l taught you the glory of %d,
- +where you studied black arts with your fellow %gp,
- +and where you were chosen for your unholy mission.
- +
- +You did not expect to be back so soon.
- +Why has %l called you?
- +
- +It is nighttime, and the moonlight is scattered by clouds. You make sure
- +to stay in the shadows, for even here you are likely to be ambushed
- +for your precious cargo. The surface is never safe for you now.
- +%E [You arrive near %H. Talk to %l to find out why %lh called you.]
- +%Cp Inf 00002
- +Once again, you near %H.
- +%E
- +%Cp Inf 00003
- +Again you face %H. %dS presence feels fainter than usual.
- +You wonder if you'll be allowed to return here yet again.
- +%E
- +# Note: %lh is just to randomize the pronoun,
- +# the unlucky hero was not actually your leader
- +%Cc Inf 00004
- +It is written in the Book of %d:
- +
- + After the Creation, the mighty %G %d rebelled
- + against the tyranny of Marduk the Creator. %d
- + defeated Marduk and obtained from him the most powerful
- + of all the artifacts of the gods, the Amulet of Yendor,
- + and %dH hid it in %dJ dark domain of Gehennom, the
- + Under World, where %dH now gathers power and prepares for
- + the final confrontation.
- +
- +Many fools were sent by the gods of the heaven after the Amulet,
- +only to die in the underground mazes. By pure luck, one of them
- +has succeeded; thankfully, %lh was ambushed on the way back
- +and the Amulet was recovered by %ds Cult.
- +
- +You, a newly trained %r, have been heralded
- +from birth as the instrument of %d. You are destined
- +to return the Amulet to its rightful owner, or die in the
- +attempt. Your hour of destiny has come. For the sake
- +of us all: Go bravely with %d!
- +%E [%dC has chosen you to return the Amulet of Yendor to %dI.]
- +%Cp Inf 00005
- +"Agents of the false gods are everywhere! I got my purse stolen!"
- +%E
- +%Cp Inf 00006
- +"I was once biten by a werewolf in %i.
- +It's not nearly as glamorous as the books make it sound."
- +%E
- +%Cp Inf 00007
- +"I just noticed a pile of skulls in that corner. %pC... are we the baddies?"
- +%E
- +# Note: this will obviously need to be rewritten
- +# if the Paladin's gender changes
- +%Cp Inf 00008
- +"%nC of %D acts all high and mighty, but %nh's still just a woman."
- +%E
- +%Cp Inf 00009
- +"We were THIS close to recovering %o by ourselves!
- +The church of %D just got lucky... and a better funding."
- +%E
- +%Cp Inf 00010
- +"Agents of the false gods are everywhere! I got my purse stolen!"
- +%E
- +%Cp Inf 00011
- +"Glory to %d, %s! Let's drink elf blood together!"
- +%E
- +%Cp Inf 00012
- +"I just noticed a pile of skulls in that corner. %pC... are we the baddies?"
- +%E
- +%Cp Inf 00013
- +"Have you made sure to properly desecrate %ns corpse?
- +Appearances are important!"
- +%E
- +%Cp Inf 00014
- +"%oC is ours! Take that, professional archeology!"
- +%E
- +%Cc Inf 00015
- +"My %S, welcome back. You must be wondering why I have interrupted
- +your mission! As it happens, another quest has arisen that
- +only you can undertake. Let me see if you're up to the challenge."
- +%E [I have another important mission for you, if you're ready.]
- +%Cp Inf 00016
- +"Welcome again, %p. I hope you're ready this time."
- +%E
- +%Cp Inf 00017
- +"Again you return, %p. %nC won't wait forever! Are you ready now?"
- +%E
- +%Cc Inf 00018
- +"I am most disappointed, %p. The fire of %d no longer
- +burns in your breast! How could you abandon your faith so easily?
- +You're no longer our %s. Begone and never return! We will
- +find someone else to finish your quest."
- +%E [You're exiled from the Cult for your lack of faith.]
- +%Cc Inf 00019
- +"Alas, %p, you're still weak. I cannot in good faith send you
- +against %n of %D now; %nh'll squash you
- +like an insect! You must train and attain more skill;
- +come back when you're a proper %R."
- +%E [%rA has no chance against %n. Come back when you are %Ra.]
- +%Cc Inf 00020
- +"No, that will not do. The fire of %d within you is too weak.
- +Only with the support of our faith can you hope to prevail!
- +Go back to %Z and perform more sacrifices to
- +honor %d. When your devotion is strong again, you may return."
- +%E [Your faith is too weak. Return when you're sufficently %a.]
- +%Cc Inf 00021
- +"Yes, my %S. You are now as ready as you'll ever be. Listen
- +carefully as I explain the current situation and your new quest.
- +
- +"As you must know, we have long searched for the lost %ot,
- +for it is vitally important both to our faith and the ultimate plan
- +of our %GC %d. But the church of %D
- +has learned of our efforts and sponsored a team of professional
- +archeologists to find %O first. Unfortunately, it seems
- +they were succesful.
- +
- +"A week ago, the Cult has received a message from a prominent %nt
- +of %D. %nH claims that %O is in
- +%nj posession, and challenges you to a `honorable duel' for the artifact.
- +%nC was adamant in dueling you specifically, so it's
- +clearly a ploy to obtain the Amulet of Yendor that was entrusted to you.
- +
- +"We have no choice but to accept, as without %O %ds plan
- +cannot be completed. %nC of %D
- +waits for you in the ancient ruins amidst %i, which
- +can be reached through the underground complex below our temple.
- +You must travel there and retrieve %o by any means.
- +
- +"%dC be your strength, %p. Go with %dJ blessing."
- +%E [%nC of %D found %o and challenged you to a duel. Kill %ni by any means.]
- +%Cp Inf 00025
- +"As long as the fire of %d burns within your chest, you will prevail."
- +%E
- +%Cp Inf 00026
- +"%nC of %D is a capable spellcaster as well as a powerful warrior.
- +Approach %ni with care and think before acting."
- +%E
- +%Cp Inf 00027
- +"%nC of %Ds faith is very strong, and as such %nh knows no fear."
- +%E
- +%Cp Inf 00028
- +"%iC is plagued by werewolves. If you can wield silver weapons, do so."
- +%E
- +%Cp Inf 00029
- +"If you know how to evoke fireballs, it will be your greatest aid.
- +%nC may be well-armored, but that won't protect %ni from burning alive!"
- +%E
- +%Cp Inf 00030
- +"%oC protects %oi holder from many harmful magics.
- +Unfortunately, %oi current holder is %n.
- +If you can somehow steal %oh, it will aid you greatly."
- +%E
- +%Cp Inf 00031
- +"When you obtain %o, you may call for %ds aid at any time.
- +Even at the surface, you will be answered."
- +%E
- +%Cp Inf 00032
- +"Watch where you aim your wands: %n of %D has a magical reflective shield."
- +%E
- +%Cp Inf 00033
- +"The church of %D wouldn't risk %O if they weren't sure %n can defeat you
- +in a fair fight. So don't fight fair!"
- +%E
- +%Cp Inf 00034
- +"%nC of %D is immune to mundane poisons, but a paralyzing venom
- +will work wonders on %ni."
- +%E
- +%Cc Inf 00035
- +The gloom and stillness of the underground caves gives way to moonlight,
- +hooting of owls, and an occasional blood-chilling howl.
- +
- +%iC lies ahead. Somewhere in these woods
- +%n of %D awaits you.
- +%E [You have reached %i. %nC is somewhere ahead.]
- +%Cp Inf 00036
- +Again, you stand at the edge of %i.
- +%E
- +%Cc Inf 00040
- +You've reached a clearing in the forest. In the distance, you can %x
- +the ancient ruins where %n of %D
- +has challenged you to the duel.
- +
- +It's still nighttime. Hopefully you can sneak up unnoticed, but what then?
- +%E [You have found the dueling field. You must proceed carefully.]
- +%Cp Inf 00041
- +Once again, you approach the ancient ruins.
- +%E
- +%Cc Inf 00050
- +"Ah, %p. You've answered my challenge, after all.
- +It seems that your vile cult has at least some recognition of honor.
- +
- +"But no matter. Your malignant existence is an affront to
- +%D, and it is by my hand that it will end today.
- +
- +"And after I defeat you and take the Amulet from your undeserving grasp,
- +I will destroy %o once and for all, and your cult
- +shall soon follow!
- +
- +"Prepare yourself, villian, for your final judgement!"
- +%E [I shall defeat you and then destroy %o and your cult.]
- +%Cp Inf 00051
- +"Again you return, %p. Did you think running away could help you somehow?"
- +%E
- +%Cp Inf 00052
- +"Surely by now you understand that you haven't got a chance.
- +Accept your fate and die, coward!"
- +%E
- +%Cp Inf 00053
- +"Wha-- how? Get back here, thief! We're not done yet!"
- +%E
- +%Cp Inf 00060
- +"%dC is a coward who can but hide underground. Aren't you ashamed
- +to be %dj slave?"
- +%E
- +%Cp Inf 00061
- +"You're a disgrace both as a combatant and as %ra. Why do I even bother?"
- +%E
- +%Cp Inf 00062
- +"I hope you like fire, because that's how you're going to spend
- +the rest of eternity."
- +%E
- +%Cp Inf 00063
- +"Ready to give up, %p? You know your %G can't help you here."
- +%E
- +%Cp Inf 00064
- +"The judgement of %D is upon you now!"
- +%E
- +%Cp Inf 00065
- +"When I claim the Amulet of Yendor for %D,
- +%d will become but a footnote in a history book."
- +%E
- +%Cp Inf 00066
- +"Did %l really think %ra could even reach the bottom of Gehennom?
- +The Amulet will be much safer with me."
- +%E
- +%Cp Inf 00067
- +"None of your fellow %gp will survive my wrath. This I promise."
- +%E
- +%Cp Inf 00068
- +"For your sins, you will die today!"
- +%E
- +%Cp Inf 00069
- +"You will never have %o, and soon, you will lose your life."
- +%E
- +%Cc Inf 00070
- +As you pick up %o, you feel the presence of %d clearer
- +than ever. The power of %d encompasses your soul, and you instantly
- +understand why your Cult was searching for %O, and why
- +%n of %D wanted to destroy %oi.
- +
- +You must return to %l at once. With %O,
- +the Cult will be more powerful than ever!
- +%E [You feel the power of %d as you touch %O; return to %l with %oi.]
- +%Cc Inf 00071
- +Very good, My pawn. Thou hast finally reached here. But where is
- +Mine %Ot that was entrusted to thee? Thou wast told to bring %oi here.
- +For thy sake, I hope thou hast not lost it!
- +
- +Return with %O and invoke My name here, and do not falter.
- +%E [Fetch %o and invoke %oi on My high altar.]
- +%Cc Inf 00072
- +"My pawn, thou hast done well. Now listen carefully, for the time
- +for thy final test has come.
- +
- +"A deity who wields the Amulet of Yendor can claim dominion over
- +the gods of the heaven, the position that is Mine by right. But I am
- +no longer welcome among them, so I must take My place by force.
- +
- +"%OC that thou carriest is a vessel for My power, and now I shall
- +make %oi the vessel for the Amulet's true power as well. Carrying %oi
- +will allow thee to journey to the Astral Plane in the heaven. There,
- +the false gods reside.
- +
- +"Find the weakest among them and invoke Mine %Ot in their temple.
- +I will take their place, and all will bow to My rule, as they should.
- +
- +"Which deity is the weakest, thou must find out thyself. Perhaps My
- +servants can advise you."
- +%E [Travel to Astral Plane and convert one of the high altars.]
- +# Note: in this message, %a and %d refer
- +# to one of the aligned gods at random.
- +# Consequently, "Moloch" is typed directly,
- +# which may break hypothetical aligned Infidels.
- +%Cc Inf 00073
- +"My %S, we all pray for thy success on thy quest. The false gods
- +posess power beyond any mere mortal, and even with Moloch's help
- +overthrowing one of them will be a challenge. Chose thine opponent wisely.
- +
- +"I'll offer thee an advice. Last night, I had a vision. There was
- +a great battle in the heaven; the forces of our Lord Moloch were besieging
- +a fortress of %d. But %dj %a minions held their
- +ground for thirty days and nights and, sadly, the fortress was not taken.
- +
- +"The meaning here is clear: when in thy mission thou reachest the heaven,
- +challenging %d will likely be futile. Keep this in mind."
- +%E [You should avoid invoking %o on the %a high altar.]
- +%Cc Inf 00080
- +%nC falls to %ni knees. With %ni last breath, %nh whispers:
- +
- + "Don't... think you've won just yet. I am but one servant of
- + %D out of many, and other gods are...
- + after you as well. You will... never reach %d alive.
- + The justice will..."
- +
- +A ray of bright light pierces the dawning sky, and %ns body is gone.
- +%E [%nC of %D dies, but others are after the Amulet.]
- +%Cc Inf 00081
- +"%pC, you are victorous! Well done. %dC is pleased
- +by your success. All of us are proud of you as well.
- +
- +"You must now continue on your original mission. But along with
- +the Amulet, you must also deliver %O to %ds Sanctum.
- +Such is %dJ will, and such is %dJ plan.
- +
- +"When you reach the high altar, the final phase of the plan will be
- +revealed to you. Remember to keep %o on you
- +at all times! If %oh's lost, all our preparations will be ruined."
- +%E [You must bring %O to %d along with the Amulet.]
- +%Cc Inf 00082
- +"You're %Os keeper now, but %d alone is %oj owner.
- +You must bring %oh to %dI along with the Amulet of Yendor.
- +%Z await your return through
- +the magic portal that brought you here."
- +%E [%OC is your responsibility now. Bring it to %d along with the Amulet.]
- +%Cp Inf 00090
- +"Welcome back, my %S. Have you found your way to Sanctum yet?"
- +%E
- +# Note: in this message, %a and %d refer
- +# to one of the aligned gods at random.
- +# Consequently, "Moloch" is typed directly,
- +# which may break hypothetical aligned Infidels.
- +%Cc Inf 00091
- +"Congratulations, %p! We are closer than ever to the ultimate victory.
- +
- +"As Moloch has told you, you must now bring %O to one of the high altars
- +on the Astral Plane. It's hard to say which deity will be more susceptible
- +to Moloch's power, but in all my years fending off non-believers,
- +I have noticed that %ap are unusually resistant to my clerical magic.
- +
- +"Perhaps that extends to %d %diself, as well."
- +%E [You should avoid invoking %o on the %a high altar.]
- +#
- # Knight
- #
- %Cc Kni 00001
- diff --git c/doc/Guidebook.mn w/doc/Guidebook.mn
- index ef41914..d21b9b9 100644
- --- c/doc/Guidebook.mn
- +++ w/doc/Guidebook.mn
- @@ -121,6 +121,11 @@ and neutralize poisons; and with their instruments, they can divine a
- being's state of health or sickness. Their medical practice earns them
- quite reasonable amounts of money, with which they enter the dungeon.
- .pg
- +\fIInfidels\fP are cultists of the evil god Moloch. They are quite
- +proficient in black magics, but less so in the physical combat. As an
- +Infidel, your goal is not to retrieve the Amulet, but to return it to its
- +hiding place within Gehennom.
- +.pg
- \fIKnights\fP are distinguished from the common skirmisher by their
- devotion to the ideals of chivalry and by the surpassing excellence of
- their armor.
- diff --git c/doc/Guidebook.tex w/doc/Guidebook.tex
- index 3a28fe0..3977436 100644
- --- c/doc/Guidebook.tex
- +++ w/doc/Guidebook.tex
- @@ -139,6 +139,12 @@ of health or sickness. Their medical practice earns them quite reasonable
- amounts of money, with which they enter the dungeon.
- %.pg
- %
- +\item[\bb{Infidels}]%
- +are cultists of the evil god Moloch. They are quite proficient in black
- +magics, but less so in the physical combat. As an Infidel, your goal is not
- +to retrieve the Amulet, but to return it to its hiding place within Gehennom.
- +%.pg
- +%
- \item[\bb{Knights}]%
- are distinguished from the common skirmisher by their
- devotion to the ideals of chivalry and by the surpassing excellence of
- diff --git c/include/artifact.h w/include/artifact.h
- index 4e5193f..49fddb6 100644
- --- c/include/artifact.h
- +++ w/include/artifact.h
- @@ -66,7 +66,8 @@ enum invoke_prop_types {
- LEV_TELE,
- CREATE_PORTAL,
- ENLIGHTENING,
- - CREATE_AMMO
- + CREATE_AMMO,
- + CHANNEL
- };
- #endif /* ARTIFACT_H */
- diff --git c/include/artilist.h w/include/artilist.h
- index d1b1ef6..f7de910 100644
- --- c/include/artilist.h
- +++ w/include/artilist.h
- @@ -29,6 +29,7 @@ static const char *artifact_names[] = {
- #define FIRE(a,b) {0,AD_FIRE,a,b}
- #define ELEC(a,b) {0,AD_ELEC,a,b} /* electrical shock */
- #define STUN(a,b) {0,AD_STUN,a,b} /* magical attack */
- +#define DREN(a,b) {0,AD_DREN,a,b} /* drains energy */
- /* clang-format on */
- STATIC_OVL NEARDATA struct artifact artilist[] = {
- @@ -163,6 +164,12 @@ STATIC_OVL NEARDATA struct artifact artilist[] = {
- PHYS(5, 0), DFNS(AD_BLND), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 1500L,
- NO_COLOR),
- + /* The energy drain only works if the artifact kills its victim.
- + * Also increases sacrifice value while wielded. */
- + A("Secespita", KNIFE, (SPFX_RESTR | SPFX_ATTK), 0, 0,
- + DREN(5, 1), NO_DFNS, NO_CARY, 0, A_CHAOTIC, PM_INFIDEL, NON_PM,
- + 1000L, NO_COLOR),
- +
- /*
- * The artifacts for the quest dungeon, all self-willed.
- */
- @@ -197,6 +204,13 @@ A("The Palantir of Westernesse", CRYSTAL_BALL,
- 0, 0, DRLI(0, 0), DRLI(0, 0), NO_CARY, HEALING, A_NEUTRAL, PM_HEALER,
- NON_PM, 5000L, NO_COLOR),
- + /* Also confers energy regeneration,
- + * but only to those in good standing with Moloch. */
- + A("The Idol of Moloch", FIGURINE,
- + (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), SPFX_HSPDAM, 0,
- + NO_ATTK, NO_DFNS, CARY(AD_MAGM), CHANNEL, A_CHAOTIC, PM_INFIDEL, NON_PM,
- + 4000L, NO_COLOR),
- +
- A("The Magic Mirror of Merlin", MIRROR,
- (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK), SPFX_ESP, 0,
- NO_ATTK, NO_DFNS, CARY(AD_MAGM), 0, A_LAWFUL, PM_KNIGHT, NON_PM, 1500L,
- diff --git c/include/context.h w/include/context.h
- index c24da8d..f876f18 100644
- --- c/include/context.h
- +++ w/include/context.h
- @@ -118,6 +118,9 @@ struct context_info {
- long next_attrib_check; /* next attribute check */
- long stethoscope_move;
- short stethoscope_movement;
- + long next_moloch_offering; /* Moloch demands regular sacrifices */
- + char inf_aligns; /* random alignment permutation number for Infidels */
- + boolean coward; /* restrict Infidel Elbereth penalty to once per move */
- boolean travel; /* find way automatically to u.tx,u.ty */
- boolean travel1; /* first travel step */
- boolean forcefight;
- diff --git c/include/extern.h w/include/extern.h
- index a1b32f7..97f3d73 100644
- --- c/include/extern.h
- +++ w/include/extern.h
- @@ -48,6 +48,7 @@ E boolean FDECL(snuff_candle, (struct obj *));
- E boolean FDECL(snuff_lit, (struct obj *));
- E boolean FDECL(catch_lit, (struct obj *));
- E void FDECL(use_unicorn_horn, (struct obj *));
- +E void FDECL(use_figurine, (struct obj **));
- E boolean FDECL(tinnable, (struct obj *));
- E void NDECL(reset_trapset);
- E void FDECL(fig_transform, (ANY_P *, long));
- @@ -70,6 +71,7 @@ E boolean FDECL(confers_luck, (struct obj *));
- E boolean FDECL(arti_reflects, (struct obj *));
- E boolean FDECL(shade_glare, (struct obj *));
- E boolean FDECL(restrict_name, (struct obj *, const char *));
- +E boolean FDECL(attacks, (int, struct obj *));
- E boolean FDECL(defends, (int, struct obj *));
- E boolean FDECL(defends_when_carried, (int, struct obj *));
- E boolean FDECL(protects, (struct obj *, BOOLEAN_P));
- @@ -485,6 +487,7 @@ E void NDECL(cancel_don);
- E int FDECL(stop_donning, (struct obj *));
- E int NDECL(Armor_off);
- E int NDECL(Armor_gone);
- +E void FDECL(check_wings, (BOOLEAN_P));
- E int NDECL(Helmet_off);
- E int NDECL(Gloves_off);
- E int NDECL(Boots_on);
- @@ -500,7 +503,7 @@ E void FDECL(Blindf_on, (struct obj *));
- E void FDECL(Blindf_off, (struct obj *));
- E int NDECL(dotakeoff);
- E int NDECL(doremring);
- -E int FDECL(cursed, (struct obj *));
- +E int FDECL(cursed, (struct obj *, BOOLEAN_P));
- E int FDECL(armoroff, (struct obj *));
- E int FDECL(canwearobj, (struct obj *, long *, BOOLEAN_P));
- E int NDECL(dowear);
- @@ -1516,7 +1519,7 @@ E boolean FDECL(big_little_match, (int, int));
- E const char *FDECL(locomotion, (const struct permonst *, const char *));
- E const char *FDECL(stagger, (const struct permonst *, const char *));
- E const char *FDECL(on_fire, (struct permonst *, struct attack *));
- -E const struct permonst *FDECL(raceptr, (struct monst *));
- +E struct permonst *FDECL(raceptr, (struct monst *));
- E boolean FDECL(olfaction, (struct permonst *));
- /* ### monmove.c ### */
- @@ -1996,6 +1999,8 @@ E boolean NDECL(stuck_in_wall);
- #ifdef USE_TRAMPOLI
- E int NDECL(prayer_done);
- #endif
- +E void FDECL(god_zaps_you, (ALIGNTYP_P));
- +E void FDECL(godvoice, (ALIGNTYP_P, const char *));
- E int NDECL(dosacrifice);
- E boolean FDECL(can_pray, (BOOLEAN_P));
- E int NDECL(dopray);
- @@ -2006,6 +2011,7 @@ E const char *FDECL(a_gname_at, (XCHAR_P x, XCHAR_P y));
- E const char *FDECL(align_gname, (ALIGNTYP_P));
- E const char *FDECL(halu_gname, (ALIGNTYP_P));
- E const char *FDECL(align_gtitle, (ALIGNTYP_P));
- +E aligntyp FDECL(inf_align, (int));
- E void FDECL(altar_wrath, (int, int));
- /* ### priest.c ### */
- @@ -2163,6 +2169,7 @@ E int FDECL(rnz, (int));
- /* ### role.c ### */
- +E int FDECL(special_alignment, (int, int));
- E boolean FDECL(validrole, (int));
- E boolean FDECL(validrace, (int, int));
- E boolean FDECL(validgend, (int, int, int));
- diff --git c/include/mondata.h w/include/mondata.h
- index 155ebfa..f793271 100644
- --- c/include/mondata.h
- +++ w/include/mondata.h
- @@ -30,6 +30,9 @@
- #define is_lminion(mon) \
- (is_minion((mon)->data) && mon_aligntyp(mon) == A_LAWFUL)
- #define is_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L)
- +/* flight blocked by most body armor */
- +#define big_wings(ptr) ((ptr) == &mons[PM_WINGED_GARGOYLE] \
- + || (ptr) == &mons[PM_DEMON])
- #define is_floater(ptr) ((ptr)->mlet == S_EYE || (ptr)->mlet == S_LIGHT)
- /* clinger: piercers, mimics, wumpus -- generally don't fall down holes */
- #define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L)
- @@ -97,6 +100,8 @@
- #define carnivorous(ptr) (((ptr)->mflags1 & M1_CARNIVORE) != 0L)
- #define herbivorous(ptr) (((ptr)->mflags1 & M1_HERBIVORE) != 0L)
- #define metallivorous(ptr) (((ptr)->mflags1 & M1_METALLIVORE) != 0L)
- +#define inediate(ptr) (((ptr)->mflags1 & (M1_CARNIVORE | M1_HERBIVORE \
- + | M1_METALLIVORE)) == 0L)
- #define polyok(ptr) (((ptr)->mflags2 & M2_NOPOLY) == 0L)
- #define is_shapeshifter(ptr) (((ptr)->mflags2 & M2_SHAPESHIFTER) != 0L)
- #define is_undead(ptr) (((ptr)->mflags2 & M2_UNDEAD) != 0L)
- diff --git c/include/monflag.h w/include/monflag.h
- index f430ced..10dd08b 100644
- --- c/include/monflag.h
- +++ w/include/monflag.h
- @@ -174,6 +174,7 @@
- #define MH_DWARF M2_DWARF
- #define MH_GNOME M2_GNOME
- #define MH_ORC M2_ORC
- +#define MH_DEMON M2_DEMON
- /* for mons[].geno (constant during game) */
- #define G_UNIQ 0x1000 /* generated only once */
- diff --git c/include/patchlevel.h w/include/patchlevel.h
- index 9133878..39aa85e 100644
- --- c/include/patchlevel.h
- +++ w/include/patchlevel.h
- @@ -14,7 +14,7 @@
- * Incrementing EDITLEVEL can be used to force invalidation of old bones
- * and save files.
- */
- -#define EDITLEVEL 0
- +#define EDITLEVEL 1
- #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
- #define COPYRIGHT_BANNER_B \
- diff --git c/include/qtext.h w/include/qtext.h
- index 7529384..9a11583 100644
- --- c/include/qtext.h
- +++ w/include/qtext.h
- @@ -64,7 +64,7 @@ struct qtlists {
- #define QT_FIRSTTIME 1
- #define QT_NEXTTIME 2
- #define QT_OTHERTIME 3
- -
- +#define QT_ALTSTART 4 /* alternate game start message (optional) */
- #define QT_GUARDTALK 5 /* 5 random things guards say before quest */
- #define QT_GUARDTALK2 10 /* 5 random things guards say after quest */
- @@ -94,6 +94,11 @@ struct qtlists {
- #define QT_GOTIT 70
- +/* For Infidels: Moloch's dialogue */
- +#define QT_MOLOCH_1 71 /* offered Amulet, no Idol */
- +#define QT_MOLOCH_2 72 /* offered Amulet, got Idol */
- +#define QT_MOLOCH_3 73 /* high priest's altar hint */
- +
- #define QT_KILLEDNEM 80
- #define QT_OFFEREDIT 81
- #define QT_OFFEREDIT2 82
- diff --git c/include/you.h w/include/you.h
- index ad178a2..72ec45f 100644
- --- c/include/you.h
- +++ w/include/you.h
- @@ -48,14 +48,13 @@ struct u_event {
- Bitfield(uopened_dbridge, 1); /* opened the drawbridge */
- Bitfield(invoked, 1); /* invoked Gate to the Sanctum level */
- Bitfield(gehennom_entered, 1); /* entered Gehennom via Valley */
- - Bitfield(uhand_of_elbereth, 2); /* became Hand of Elbereth */
- + Bitfield(uhand_of_elbereth, 3); /* became Hand of Elbereth */
- Bitfield(udemigod, 1); /* killed the wiz */
- - Bitfield(uvibrated, 1); /* stepped on "vibrating square" */
- Bitfield(ascended, 1); /* has offered the Amulet */
- };
- struct u_achieve {
- - Bitfield(amulet, 1); /* touched Amulet */
- + Bitfield(amulet, 1); /* touched (for Infidels: offered) Amulet */
- Bitfield(bell, 1); /* touched Bell */
- Bitfield(book, 1); /* touched Book */
- Bitfield(menorah, 1); /* touched Candelabrum */
- @@ -66,6 +65,7 @@ struct u_achieve {
- Bitfield(finish_sokoban, 1); /* obtained the sokoban prize */
- Bitfield(killed_medusa, 1);
- + Bitfield(vibrating_square, 1); /* stepped on "vibrating square" */
- };
- struct u_realtime {
- @@ -219,6 +219,7 @@ struct Race {
- };
- extern const struct Race races[]; /* Table of available races */
- +extern struct Race race_demon; /* used in pray.c */
- extern struct Race urace;
- #define Race_if(X) (urace.malenum == (X))
- #define Race_switch (urace.malenum)
- diff --git c/include/youprop.h w/include/youprop.h
- index c9656aa..c0f41a5 100644
- --- c/include/youprop.h
- +++ w/include/youprop.h
- @@ -227,11 +227,13 @@
- #define HFlying u.uprops[FLYING].intrinsic
- #define EFlying u.uprops[FLYING].extrinsic
- /* BFlying has I_SPECIAL set if levitating or trapped in the floor or both,
- - FROMOUTSIDE set if inside solid rock (or in water on Plane of Water) */
- + FROMOUTSIDE set if inside solid rock (or in water on Plane of Water)
- + W_ARM set if in big_wings() form and wearing blocking body armor
- + (the last one obviously won't block the steed from flying) */
- #define BFlying u.uprops[FLYING].blocked
- -#define Flying \
- - ((HFlying || EFlying || (u.usteed && is_flyer(u.usteed->data))) \
- - && !BFlying)
- +#define Flying \
- + (((HFlying || EFlying) && !BFlying \
- + || u.usteed && is_flyer(u.usteed->data)) && !(BFlying & ~W_ARMOR))
- /* May touch surface; does not override any others */
- #define EWwalking u.uprops[WWALKING].extrinsic
- @@ -372,6 +374,6 @@
- redundant but allows the function calls to be skipped most of the time */
- #define Unaware (multi < 0 && (unconscious() || is_fainted()))
- -#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(youmonst.data))
- +#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(raceptr(&youmonst)))
- #endif /* YOUPROP_H */
- diff --git c/src/allmain.c w/src/allmain.c
- index 5111c69..8ea4087 100644
- --- c/src/allmain.c
- +++ w/src/allmain.c
- @@ -226,7 +226,13 @@ boolean resuming;
- && ((wtcap < MOD_ENCUMBER
- && (!(moves % ((MAXULEV + 8 - u.ulevel)
- * (Role_if(PM_WIZARD) ? 3 : 4)
- - / 6)))) || Energy_regeneration)) {
- + / 6)))) || Energy_regeneration
- + /* the Idol grants energy regen to piously unaligned;
- + * it really shouldn't be restricted to Infidels,
- + * but so far we have no other unaligned roles */
- + || Role_if(PM_INFIDEL) && u.uhave.questart
- + && u.ualign.type == A_NONE
- + && u.ualign.record > rn2(20))) {
- u.uen += rn1(
- (int) (ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1, 1);
- if (u.uen > u.uenmax)
- @@ -236,6 +242,48 @@ boolean resuming;
- interrupt_multi("You feel full of energy.");
- }
- + /* Moloch demands regular sacrifices! */
- + if (context.next_moloch_offering <= moves) {
- + if (context.next_moloch_offering == moves
- + && (u.ualign.type == A_NONE
- + || u.ualignbase[A_CURRENT] == A_NONE)) {
- + You_feel("%s urge to perform a sacrifice.",
- + u.ualign.type == A_NONE ? "an"
- + : "a faint");
- + stop_occupation();
- + }
- + if (u.ualign.type == A_NONE && !rn2(10)
- + && rn2(moves - context.next_moloch_offering
- + + 1000) >= 1000) {
- + if (u.ualign.record > -99)
- + adjalign(-1);
- + if (u.ualign.record < -10 && !rn2(u.ugangr + 1)
- + && rn2(-u.ualign.record + 90) >= 100) {
- + char *angry = (char *) 0;
- + u.ugangr++;
- + /* avoid repetitive messages */
- + switch (u.ugangr) {
- + /* same values as in cmd.c */
- + case 1:
- + angry = "";
- + break;
- + case 4:
- + angry = "very ";
- + break;
- + case 7:
- + angry = "extremely ";
- + break;
- + }
- + if (angry) {
- + You_feel("that %s is %sangry at your "
- + "lack of offerings.", u_gname(),
- + angry);
- + stop_occupation();
- + }
- + }
- + }
- + }
- +
- if (!u.uinvulnerable) {
- if (Teleportation && !rn2(85)) {
- xchar old_ux = u.ux, old_uy = u.uy;
- @@ -336,6 +384,7 @@ boolean resuming;
- /* when/if hero escapes from lava, he can't just stay there */
- else if (!u.umoved)
- (void) pooleffects(FALSE);
- + context.coward = FALSE;
- } /* actual time passed */
- @@ -590,6 +639,9 @@ newgame()
- context.next_attrib_check = 600L; /* arbitrary first setting */
- context.tribute.enabled = TRUE; /* turn on 3.6 tributes */
- context.tribute.tributesz = sizeof(struct tribute_info);
- + context.inf_aligns = rn2(6); /* randomness for the Infidel role */
- + context.next_moloch_offering = 6000; /* give a grace period before
- + * the first sacrifice */
- for (i = LOW_PM; i < NUMMONS; i++)
- mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;
- diff --git c/src/apply.c w/src/apply.c
- index e77984d..a7fd5e2 100644
- --- c/src/apply.c
- +++ w/src/apply.c
- @@ -22,7 +22,6 @@ STATIC_DCL void FDECL(use_lamp, (struct obj *));
- STATIC_DCL void FDECL(light_cocktail, (struct obj **));
- STATIC_PTR void FDECL(display_jump_positions, (int));
- STATIC_DCL void FDECL(use_tinning_kit, (struct obj *));
- -STATIC_DCL void FDECL(use_figurine, (struct obj **));
- STATIC_DCL void FDECL(use_grease, (struct obj *));
- STATIC_DCL void FDECL(use_trap, (struct obj *));
- STATIC_DCL void FDECL(use_stone, (struct obj *));
- @@ -2105,6 +2104,7 @@ long timeout;
- boolean cansee_spot, silent, okay_spot;
- boolean redraw = FALSE;
- boolean suppress_see = FALSE;
- + boolean idol = figurine && figurine->oartifact == ART_IDOL_OF_MOLOCH;
- char monnambuf[BUFSZ], carriedby[BUFSZ];
- if (!figurine) {
- @@ -2115,7 +2115,8 @@ long timeout;
- okay_spot = get_obj_location(figurine, &cc.x, &cc.y, 0);
- if (figurine->where == OBJ_INVENT || figurine->where == OBJ_MINVENT)
- okay_spot = enexto(&cc, cc.x, cc.y, &mons[figurine->corpsenm]);
- - if (!okay_spot || !figurine_location_checks(figurine, &cc, TRUE)) {
- + if (idol && figurine->age > timeout || !okay_spot
- + || !figurine_location_checks(figurine, &cc, TRUE)) {
- /* reset the timer to try again later */
- (void) start_timer((long) rnd(5000), TIMER_OBJECT, FIG_TRANSFORM,
- obj_to_any(figurine));
- @@ -2159,9 +2160,14 @@ long timeout;
- case OBJ_FLOOR:
- if (cansee_spot && !silent) {
- - if (suppress_see)
- + if (idol) {
- + if (!suppress_see)
- + You_see("a cloud of %s mist coagulate "
- + "into the shape of %s%s!",
- + hcolor("crimson"), monnambuf, and_vanish);
- + } else if (suppress_see) {
- pline("%s suddenly vanishes!", an(xname(figurine)));
- - else
- + } else
- You_see("a figurine transform into %s%s!", monnambuf,
- and_vanish);
- redraw = TRUE; /* update figurine's map location */
- @@ -2197,12 +2203,20 @@ long timeout;
- break;
- }
- }
- - /* free figurine now */
- - if (carried(figurine)) {
- - useup(figurine);
- + if (idol) {
- + long cooldown = rnz(100);
- + figurine->age = timeout + cooldown;
- + /* still cursed */
- + (void) start_timer((long) rnd(9000) + cooldown, TIMER_OBJECT,
- + FIG_TRANSFORM, obj_to_any(figurine));
- } else {
- - obj_extract_self(figurine);
- - obfree(figurine, (struct obj *) 0);
- + /* free figurine now */
- + if (carried(figurine)) {
- + useup(figurine);
- + } else {
- + obj_extract_self(figurine);
- + obfree(figurine, (struct obj *) 0);
- + }
- }
- if (redraw)
- newsym(cc.x, cc.y);
- @@ -2244,14 +2258,26 @@ boolean quietly;
- return TRUE;
- }
- -STATIC_OVL void
- +void
- use_figurine(optr)
- struct obj **optr;
- {
- register struct obj *obj = *optr;
- + boolean idol = obj->oartifact == ART_IDOL_OF_MOLOCH;
- xchar x, y;
- coord cc;
- + char *release_figurine;
- + if (idol) {
- + /* copied from artifact.c */
- + if (obj->age > monstermoves) {
- + You_feel("that %s %s ignoring you.", the(xname(obj)),
- + otense(obj, "are"));
- + obj->age += (long) d(3, 10);
- + return;
- + }
- + obj->age = monstermoves + rnz(100);
- + }
- if (u.uswallow) {
- /* can't activate a figurine while swallowed */
- if (!figurine_location_checks(obj, (coord *) 0, FALSE))
- @@ -2268,17 +2294,33 @@ struct obj **optr;
- /* Passing FALSE arg here will result in messages displayed */
- if (!figurine_location_checks(obj, &cc, FALSE))
- return;
- - You("%s and it %stransforms.",
- - (u.dx || u.dy) ? "set the figurine beside you"
- - : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
- - || is_pool(cc.x, cc.y))
- - ? "release the figurine"
- - : (u.dz < 0 ? "toss the figurine into the air"
- - : "set the figurine on the ground"),
- - Blind ? "supposedly " : "");
- + if (u.dx || u.dy)
- + release_figurine = "set the figurine beside you";
- + else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
- + || is_pool(cc.x, cc.y))
- + release_figurine = "release the figurine";
- + else if (u.dz < 0)
- + release_figurine = "toss the figurine into the air";
- + else
- + release_figurine = "set the figurine on the ground";
- + if (idol) {
- + if (Blind)
- + You("%s and feel an unholy aura emanate from it.",
- + release_figurine);
- + else
- + You("%s and a cloud of %s mist arises from it.",
- + release_figurine, hcolor("crimson"));
- + } else
- + You("%s and it %stransforms.", release_figurine,
- + Blind ? "supposedly " : "");
- (void) make_familiar(obj, cc.x, cc.y, FALSE);
- - (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
- - useup(obj);
- + if (idol) {
- + freeinv(obj);
- + place_object(obj, cc.x, cc.y);
- + } else {
- + (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
- + useup(obj);
- + }
- if (Blind)
- map_invisible(cc.x, cc.y);
- *optr = 0;
- @@ -3595,7 +3637,7 @@ doapply()
- case BLINDFOLD:
- case LENSES:
- if (obj == ublindf) {
- - if (!cursed(obj))
- + if (!cursed(obj, FALSE))
- Blindf_off(obj);
- } else if (!ublindf) {
- Blindf_on(obj);
- diff --git c/src/artifact.c w/src/artifact.c
- index 03573fe..4616e65 100644
- --- c/src/artifact.c
- +++ w/src/artifact.c
- @@ -6,6 +6,7 @@
- #include "hack.h"
- #include "artifact.h"
- #include "artilist.h"
- +#include "qtext.h"
- /*
- * Note: both artilist[] and artiexist[] have a dummy element #0,
- @@ -50,7 +51,7 @@ static boolean artiexist[1 + NROFARTIFACTS + 1];
- STATIC_OVL xchar artidisco[NROFARTIFACTS];
- STATIC_DCL void NDECL(hack_artifacts);
- -STATIC_DCL boolean FDECL(attacks, (int, struct obj *));
- +STATIC_DCL void FDECL(fix_artifact, (struct obj *));
- /* handle some special cases; must be called after u_init() */
- STATIC_OVL void
- @@ -102,6 +103,19 @@ int fd;
- hack_artifacts(); /* redo non-saved special cases */
- }
- +/* Some artifacts may need additional tweaking when created.
- + * Called when the artifact is christened.
- + */
- +STATIC_DCL void
- +fix_artifact(otmp)
- +struct obj *otmp;
- +{
- + if (otmp->oartifact == ART_IDOL_OF_MOLOCH) {
- + set_corpsenm(otmp, PM_HORNED_DEVIL);
- + otmp->spe = 0;
- + }
- +}
- +
- const char *
- artiname(artinum)
- int artinum;
- @@ -129,8 +143,8 @@ aligntyp alignment; /* target alignment, or A_NONE */
- {
- const struct artifact *a;
- int m, n, altn;
- - boolean by_align = (alignment != A_NONE);
- - short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
- + boolean by_align = alignment != A_NONE || !otmp;
- + short o_typ = by_align ? 0 : otmp->otyp;
- boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
- short eligible[NROFARTIFACTS];
- @@ -199,6 +213,7 @@ aligntyp alignment; /* target alignment, or A_NONE */
- otmp = oname(otmp, a->name);
- otmp->oartifact = m;
- artiexist[m] = TRUE;
- + fix_artifact(otmp);
- }
- } else {
- /* nothing appropriate could be found; return original object */
- @@ -271,6 +286,8 @@ boolean mod;
- if (otmp->otyp == RIN_INCREASE_DAMAGE)
- otmp->spe = 0;
- artiexist[m] = mod;
- + if (mod)
- + fix_artifact(otmp);
- break;
- }
- return;
- @@ -404,7 +421,7 @@ const char *name;
- return FALSE;
- }
- -STATIC_OVL boolean
- +boolean
- attacks(adtyp, otmp)
- int adtyp;
- struct obj *otmp;
- @@ -799,6 +816,8 @@ struct monst *mtmp;
- return !(yours ? Poison_resistance : resists_poison(mtmp));
- case AD_DRLI:
- return !(yours ? Drain_resistance : resists_drli(mtmp));
- + case AD_DREN:
- + return !nonliving(ptr);
- case AD_STON:
- return !(yours ? Stone_resistance : resists_ston(mtmp));
- default:
- @@ -1602,6 +1621,89 @@ struct obj *obj;
- nhUse(otmp);
- break;
- }
- + case CHANNEL:
- + /* Should this break atheist conduct? Currently it doesn't,
- + * under the excuse of being necessary to ascend.
- + * But still, we're channeling a god's power here... */
- + if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
- + aligntyp altar_align = Amask2align(levl[u.ux][u.uy].altarmask
- + & AM_MASK);
- + boolean high_altar = (Is_astralevel(&u.uz)
- + || Is_sanctum(&u.uz))
- + && (levl[u.ux][u.uy].altarmask
- + & AM_SHRINE);
- + if (!Blind)
- + pline("Tendrils of %s mist seep out of %s "
- + "and into the altar below...",
- + hcolor("crimson"), the(xname(obj)));
- + else
- + You_feel("something flow from %s.", the(xname(obj)));
- + if (altar_align == A_NONE) {
- + if (high_altar && Role_if(PM_INFIDEL)
- + && u.uachieve.amulet && !obj->spe) {
- + godvoice(A_NONE, (char *) 0);
- + qt_pager(QT_MOLOCH_2);
- + You_feel("strange energies envelop %s.",
- + the(xname(obj)));
- + obj->spe = 1;
- + u.uhave.amulet = 1;
- + break;
- + }
- + if (!Blind)
- + pline_The("altar glows for a moment.");
- + /* nothing happens */
- + break;
- + }
- + if (high_altar) {
- + /* messages yoinked from pray.c */
- + You("sense a conflict between %s and %s.",
- + align_gname(A_NONE), a_gname());
- + if (obj->spe && altar_align == inf_align(1)) {
- + You_feel("the power of %s increase.",
- + align_gname(A_NONE));
- + } else {
- + pline("%s feel the power of %s decrease.",
- + u.ualign.type == A_NONE ? "Unluckily, you"
- + : "You",
- + align_gname(A_NONE));
- + godvoice(altar_align, "So, mortal! You dare "
- + "desecrate my High Temple!");
- + god_zaps_you(altar_align);
- + break;
- + }
- + }
- + levl[u.ux][u.uy].altarmask &= AM_SHRINE;
- + levl[u.ux][u.uy].altarmask |= AM_NONE;
- + if (!Blind)
- + pline_The("altar glows %s.", hcolor(NH_RED));
- + if (!high_altar) {
- + /* the Idol does all the work for you,
- + * so you don't get a luck increase;
- + * but you don't get a hostile minion, either */
- + struct monst *pri = findpriest(temple_occupied(u.urooms));
- + if (pri && mon_aligntyp(pri) != A_NONE)
- + angry_priest();
- + } else {
- + /* At this point, the player must be an Infidel.
- + * Should we still check for opposite alignment?
- + * Currently, Moloch doesn't care. */
- + adjalign(10);
- + u.uachieve.ascended = 1;
- + pline1("A sinister laughter echoes through the temple, "
- + "and you're bathed in darkness...");
- + godvoice(A_NONE, "My pawn, thou hast done well!");
- + display_nhwindow(WIN_MESSAGE, FALSE);
- + verbalize("In return for thy service, "
- + "I grant thee a part of My domain!");
- + You("ascend to the status of Demon %s...",
- + flags.female ? "Lady" : "Lord");
- + done(ASCENDED);
- + }
- + } else {
- + obj->age = 0; /* will be set below */
- + use_figurine(&obj);
- + }
- + break;
- }
- } else {
- long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
- diff --git c/src/attrib.c w/src/attrib.c
- index 028eebf..94ba766 100644
- --- c/src/attrib.c
- +++ w/src/attrib.c
- @@ -41,6 +41,11 @@ static const struct innate {
- { 15, &(HWarning), "sensitive", "" },
- { 0, 0, 0, 0 } },
- + inf_abil[] = { { 1, &(HFire_resistance), "", "" },
- + { 15, &(HWarning), "sensitive", "" },
- + { 20, &(HShock_resistance), "inured", "softened" },
- + { 0, 0, 0, 0 } },
- +
- kni_abil[] = { { 7, &(HFast), "quick", "slow" }, { 0, 0, 0, 0 } },
- mon_abil[] = { { 1, &(HFast), "", "" },
- @@ -101,6 +106,15 @@ static const struct innate {
- { 1, &HPoison_resistance, "", "" },
- { 0, 0, 0, 0 } },
- + dem_abil[] = { { 1, &HInfravision, "", "" },
- + { 1, &HFire_resistance, "", "" },
- + { 1, &HPoison_resistance, "", "" },
- + { 1, &HDrain_resistance, "", "" },
- + { 1, &HSee_invisible, "", "" },
- + { 1, &HFlying, "", "" },
- + /* also inediate */
- + { 0, 0, 0, 0 } },
- +
- hum_abil[] = { { 0, 0, 0, 0 } };
- STATIC_DCL void NDECL(exerper);
- @@ -706,6 +720,7 @@ int r;
- { PM_BARBARIAN, bar_abil },
- { PM_CAVEMAN, cav_abil },
- { PM_HEALER, hea_abil },
- + { PM_INFIDEL, inf_abil },
- { PM_KNIGHT, kni_abil },
- { PM_MONK, mon_abil },
- { PM_PRIEST, pri_abil },
- @@ -747,6 +762,9 @@ long frommask;
- case PM_ORC:
- abil = orc_abil;
- break;
- + case PM_DEMON:
- + abil = dem_abil;
- + break;
- case PM_HUMAN:
- abil = hum_abil;
- break;
- @@ -800,6 +818,8 @@ int propidx;
- return FROM_LYCN;
- if (propidx == FAST && Very_fast)
- return FROM_NONE; /* can't become very fast innately */
- + if (propidx == FLYING && (BFlying & W_ARMOR))
- + return FROM_NONE; /* not from form, as that is blocked */
- if ((innateness = innately(&u.uprops[propidx].intrinsic)) != FROM_NONE)
- return innateness;
- if (propidx == JUMPING && Role_if(PM_KNIGHT)
- diff --git c/src/botl.c w/src/botl.c
- index 4c7dbf3..f841d63 100644
- --- c/src/botl.c
- +++ w/src/botl.c
- @@ -84,9 +84,10 @@ do_statusline1()
- ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS),
- ACURR(A_CHA));
- Sprintf(nb = eos(nb),
- - (u.ualign.type == A_CHAOTIC)
- - ? " Chaotic"
- - : (u.ualign.type == A_NEUTRAL) ? " Neutral" : " Lawful");
- + (u.ualign.type == A_NONE) ? " Unaligned"
- + : (u.ualign.type == A_CHAOTIC) ? " Chaotic"
- + : (u.ualign.type == A_NEUTRAL) ? " Neutral"
- + : " Lawful");
- #ifdef SCORE_ON_BOTL
- if (flags.showscore)
- Sprintf(nb = eos(nb), " S:%ld", botl_score());
- @@ -623,11 +624,13 @@ bot_via_windowport()
- blstats[idx][BL_CH].a.a_int = ACURR(A_CHA);
- /* Alignment */
- - Strcpy(blstats[idx][BL_ALIGN].val, (u.ualign.type == A_CHAOTIC)
- - ? "Chaotic"
- - : (u.ualign.type == A_NEUTRAL)
- - ? "Neutral"
- - : "Lawful");
- + Strcpy(blstats[idx][BL_ALIGN].val, (u.ualign.type == A_NONE)
- + ? "Unaligned"
- + : (u.ualign.type == A_CHAOTIC)
- + ? "Chaotic"
- + : (u.ualign.type == A_NEUTRAL)
- + ? "Neutral"
- + : "Lawful");
- /* Score */
- blstats[idx][BL_SCORE].a.a_long =
- diff --git c/src/cmd.c w/src/cmd.c
- index 6b28524..3214d2a 100644
- --- c/src/cmd.c
- +++ w/src/cmd.c
- @@ -1833,7 +1833,7 @@ int unused_mode UNUSED;
- int final;
- {
- const char *role_titl, *rank_titl;
- - int innategend, difgend, difalgn;
- + int innategend, difgend, difalgn, difrace;
- char buf[BUFSZ], tmpbuf[BUFSZ];
- /* note that if poly'd, we need to use u.mfemale instead of flags.female
- @@ -1911,12 +1911,14 @@ int final;
- trailing "and" on all three aligned entries but looks too verbose] */
- Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
- if (u.ualign.type != A_LAWFUL)
- - Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
- - align_str(A_LAWFUL));
- + Sprintf(eos(buf), " %s (%s)%s", align_gname(A_LAWFUL),
- + align_str(A_LAWFUL),
- + (u.ualign.type != A_NONE) ? " and" : ",");
- if (u.ualign.type != A_NEUTRAL)
- Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
- align_str(A_NEUTRAL),
- - (u.ualign.type != A_CHAOTIC) ? " and" : "");
- + (u.ualign.type == A_NONE) ? ", and" /* oxford comma */
- + : (u.ualign.type != A_CHAOTIC) ? " and" : "");
- if (u.ualign.type != A_CHAOTIC)
- Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
- align_str(A_CHAOTIC));
- @@ -1931,12 +1933,26 @@ int final;
- difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
- + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
- ? 2 : 0));
- + difrace = urace.malenum != races[flags.initrace].malenum;
- if (difalgn & 1) { /* have temporary alignment so report permanent one */
- Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
- you_are(buf, "");
- difalgn &= ~1; /* suppress helm from "started out <foo>" message */
- }
- - if (difgend || difalgn) { /* sex change or perm align change or both */
- + if (difrace) { /* permanent race change (Inf crowning) */
- + buf[0] = '\0';
- + if (difalgn) {
- + Strcat(buf, align_str(u.ualignbase[A_ORIGINAL]));
- + Strcat(buf, " ");
- + }
- + if (difgend) {
- + Strcat(buf, genders[flags.initgend].adj);
- + Strcat(buf, " ");
- + }
- + Strcat(buf, races[flags.initrace].noun);
- + Sprintf(buf, " You started out as %s.", an(buf));
- + enlght_out(buf);
- + } else if (difgend || difalgn) { /* sex change or perm align change */
- Sprintf(buf, " You started out %s%s%s.",
- difgend ? genders[flags.initgend].adj : "",
- (difgend && difalgn) ? " and " : "",
- @@ -2494,6 +2510,25 @@ int final;
- enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
- }
- }
- + /* In case the player missed the "urge to perform a sacrifice",
- + * put a reminder here. */
- + if (u.ualign.type == A_NONE) {
- + long due = moves - context.next_moloch_offering;
- + if (due < 0) {
- + if (wizard) {
- + Sprintf(buf, "%ld turns until your next "
- + "mandatory sacrifice to ", -due);
- + you_have(buf, u_gname());
- + }
- + } else {
- + if (wizard && due > 0)
- + Sprintf(buf, "%ld turns late for your "
- + "next sacrifice to ", due);
- + else
- + Strcpy(buf, "due for a sacrifice to ");
- + you_are(buf, u_gname());
- + }
- + }
- /* hunger/nutrition */
- if (Hunger) {
- if (magic || cause_known(HUNGER))
- @@ -2624,9 +2659,10 @@ int final;
- enlght_out(final ? "Final Attributes:" : "Current Attributes:");
- if (u.uevent.uhand_of_elbereth) {
- - static const char *const hofe_titles[3] = { "the Hand of Elbereth",
- + static const char *const hofe_titles[4] = { "the Hand of Elbereth",
- "the Envoy of Balance",
- - "the Glory of Arioch" };
- + "the Glory of Arioch",
- + "a demon of Moloch" };
- you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
- }
- @@ -2795,7 +2831,7 @@ int final;
- BLevitation = save_BLev;
- }
- /* actively flying handled earlier as a status condition */
- - if (BFlying) { /* flight is blocked */
- + if (BFlying && !Flying) { /* flight is blocked */
- long save_BFly = BFlying;
- BFlying = 0L;
- @@ -2817,7 +2853,9 @@ int final;
- ? if_surroundings_permitted
- /* two or more of levitation, surroundings,
- and being trapped in the floor */
- - : " if circumstances permitted",
- + : (save_BFly == W_ARM)
- + ? " if your wings weren't confined"
- + : " if circumstances permitted",
- "");
- }
- BFlying = save_BFly;
- diff --git c/src/do.c w/src/do.c
- index 8bbed39..bb3e53b 100644
- --- c/src/do.c
- +++ w/src/do.c
- @@ -1295,10 +1295,12 @@ boolean at_stairs, falling, portal;
- * -1 11.46 12.50 12.5
- * -2 5.21 4.17 0.0
- * -3 2.08 0.0 0.0
- + *
- + * Infidels (unaligned) are spared from the mysterious force.
- */
- if (Inhell && up && u.uhave.amulet && !newdungeon && !portal
- && (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
- - if (!rn2(4)) {
- + if (u.ualign.type != A_NONE && !rn2(4)) {
- int odds = 3 + (int) u.ualign.type, /* 2..4 */
- diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */
- @@ -1707,7 +1709,8 @@ final_level()
- create_mplayers(rn1(4, 3), TRUE);
- /* create a guardian angel next to player, if worthy */
- - gain_guardian_angel();
- + if (u.ualign.type != A_NONE)
- + gain_guardian_angel();
- }
- static char *dfr_pre_msg = 0, /* pline() before level change */
- diff --git c/src/do_wear.c w/src/do_wear.c
- index b48c69d..d220c94 100644
- --- c/src/do_wear.c
- +++ w/src/do_wear.c
- @@ -414,7 +414,7 @@ Helmet_on(VOID_ARGS)
- by hero falling onto a polymorph trap or into water (emergency
- disrobe) or maybe lava (probably not, helm isn't 'organic') */
- uchangealign((u.ualign.type != A_NEUTRAL)
- - ? -u.ualign.type
- + ? -sgn(u.ualign.type)
- : (uarmh->o_id % 2) ? A_CHAOTIC : A_LAWFUL,
- 1);
- /* makeknown(HELM_OF_OPPOSITE_ALIGNMENT); -- below, after Tobjnam() */
- @@ -696,6 +696,7 @@ Armor_on(VOID_ARGS)
- */
- if (uarm) /* no known instances of !uarm here but play it safe */
- uarm->known = 1; /* suit's +/- evident because of status line AC */
- + check_wings(FALSE);
- return 0;
- }
- @@ -705,6 +706,7 @@ Armor_off(VOID_ARGS)
- context.takeoff.mask &= ~W_ARM;
- setworn((struct obj *) 0, W_ARM);
- context.takeoff.cancelled_don = FALSE;
- + check_wings(FALSE);
- return 0;
- }
- @@ -720,9 +722,44 @@ Armor_gone()
- context.takeoff.mask &= ~W_ARM;
- setnotworn(uarm);
- context.takeoff.cancelled_don = FALSE;
- + check_wings(FALSE);
- return 0;
- }
- +/* Some monster forms' flight is blocked by most body armor. */
- +void
- +check_wings(silent)
- +boolean silent; /* we assume a wardrobe change if false */
- +{
- + static struct obj *last_worn_armor;
- + boolean old_flying = Flying;
- +
- + BFlying &= ~W_ARM;
- + if (!big_wings(raceptr(&youmonst)))
- + return;
- +
- + if (!uarm) {
- + if (!silent && Flying && !old_flying)
- + You("spread your wings and take flight.");
- + } else if (Is_dragon_scales(uarm)) {
- + if (!silent && uarm != last_worn_armor)
- + You("arrange the scales around your wings.");
- + } else if (uarm->otyp == LEATHER_JACKET) {
- + if (!silent && uarm != last_worn_armor)
- + pline1("This jacket seems to have holes for wings.");
- + } else {
- + BFlying |= W_ARM;
- + if (!silent)
- + You("fold your wings under your suit.");
- + }
- +
- + if (uarm)
- + last_worn_armor = uarm;
- +
- + if (Flying != old_flying)
- + context.botl = TRUE;
- +}
- +
- STATIC_OVL void
- Amulet_on()
- {
- @@ -1546,31 +1583,35 @@ doremring()
- /* Check if something worn is cursed _and_ unremovable. */
- int
- -cursed(otmp)
- +cursed(otmp, silent)
- struct obj *otmp;
- +boolean silent;
- {
- if (!otmp) {
- impossible("cursed without otmp");
- return 0;
- }
- - /* Curses, like chickens, come home to roost. */
- - if ((otmp == uwep) ? welded(otmp) : (int) otmp->cursed) {
- - boolean use_plural = (is_boots(otmp) || is_gloves(otmp)
- - || otmp->otyp == LENSES || otmp->quan > 1L);
- -
- - /* might be trying again after applying grease to hands */
- - if (Glib && otmp->bknown
- - /* for weapon, we'll only get here via 'A )' */
- - && (uarmg ? (otmp == uwep)
- - : ((otmp->owornmask & (W_WEP | W_RING)) != 0)))
- - pline("Despite your slippery %s, you can't.",
- - fingers_or_gloves(TRUE));
- - else
- - You("can't. %s cursed.", use_plural ? "They are" : "It is");
- - set_bknown(otmp, 1);
- + /* Inf are immune to curses. */
- + if (Role_if(PM_INFIDEL) || !otmp->cursed || otmp == uwep && !welded(otmp))
- + return 0;
- + if (silent)
- return 1;
- - }
- - return 0;
- +
- + /* Curses, like chickens, come home to roost. */
- + boolean use_plural = (is_boots(otmp) || is_gloves(otmp)
- + || otmp->otyp == LENSES || otmp->quan > 1L);
- +
- + /* might be trying again after applying grease to hands */
- + if (Glib && otmp->bknown
- + /* for weapon, we'll only get here via 'A )' */
- + && (uarmg ? (otmp == uwep)
- + : ((otmp->owornmask & (W_WEP | W_RING)) != 0)))
- + pline("Despite your slippery %s, you can't.",
- + fingers_or_gloves(TRUE));
- + else
- + You("can't. %s cursed.", use_plural ? "They are" : "It is");
- + set_bknown(otmp, 1);
- + return 1;
- }
- int
- @@ -1581,7 +1622,7 @@ struct obj *otmp;
- int delay = -objects[otmp->otyp].oc_delay;
- const char *what = 0;
- - if (cursed(otmp))
- + if (cursed(otmp, FALSE))
- return 0;
- /* this used to make assumptions about which types of armor had
- delays and which didn't; now both are handled for all types */
- @@ -2280,13 +2321,13 @@ int otyp;
- /* reasons ring can't be removed match those checked by select_off();
- limbless case has extra checks because ordinarily it's temporary */
- if (nolimbs(youmonst.data) && uamul
- - && uamul->otyp == AMULET_OF_UNCHANGING && uamul->cursed)
- + && uamul->otyp == AMULET_OF_UNCHANGING && cursed(uamul, TRUE))
- return uamul;
- if (welded(uwep) && (ring == uright || bimanual(uwep)))
- return uwep;
- - if (uarmg && uarmg->cursed)
- + if (uarmg && cursed(uarmg, TRUE))
- return uarmg;
- - if (ring->cursed)
- + if (cursed(ring, TRUE))
- return ring;
- /* normally outermost layer is processed first, but slippery gloves
- wears off quickly so uncurse ring itself before handling those */
- @@ -2395,7 +2436,7 @@ register struct obj *otmp;
- ; /* some items can be removed even when cursed */
- } else {
- /* otherwise, this is fundamental */
- - if (cursed(otmp))
- + if (cursed(otmp, FALSE))
- return 0;
- }
- @@ -2442,7 +2483,7 @@ do_takeoff()
- context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */
- if (doff->what == W_WEP) {
- - if (!cursed(uwep)) {
- + if (!cursed(uwep, FALSE)) {
- setuwep((struct obj *) 0);
- You("are empty %s.", body_part(HANDED));
- u.twoweap = FALSE;
- @@ -2456,46 +2497,46 @@ do_takeoff()
- You("no longer have ammunition readied.");
- } else if (doff->what == WORN_ARMOR) {
- otmp = uarm;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Armor_off();
- } else if (doff->what == WORN_CLOAK) {
- otmp = uarmc;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Cloak_off();
- } else if (doff->what == WORN_BOOTS) {
- otmp = uarmf;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Boots_off();
- } else if (doff->what == WORN_GLOVES) {
- otmp = uarmg;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Gloves_off();
- } else if (doff->what == WORN_HELMET) {
- otmp = uarmh;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Helmet_off();
- } else if (doff->what == WORN_SHIELD) {
- otmp = uarms;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Shield_off();
- } else if (doff->what == WORN_SHIRT) {
- otmp = uarmu;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- (void) Shirt_off();
- } else if (doff->what == WORN_AMUL) {
- otmp = uamul;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- Amulet_off();
- } else if (doff->what == LEFT_RING) {
- otmp = uleft;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- Ring_off(uleft);
- } else if (doff->what == RIGHT_RING) {
- otmp = uright;
- - if (!cursed(otmp))
- + if (!cursed(otmp, FALSE))
- Ring_off(uright);
- } else if (doff->what == WORN_BLINDF) {
- - if (!cursed(ublindf))
- + if (!cursed(ublindf, FALSE))
- Blindf_off(ublindf);
- } else {
- impossible("do_takeoff: taking off %lx", doff->what);
- diff --git c/src/dog.c w/src/dog.c
- index 5c50eb6..bba4477 100644
- --- c/src/dog.c
- +++ w/src/dog.c
- @@ -75,10 +75,16 @@ boolean quietly;
- struct permonst *pm;
- struct monst *mtmp = 0;
- int chance, trycnt = 100;
- + boolean idol = otmp && otmp->oartifact == ART_IDOL_OF_MOLOCH;
- do {
- if (otmp) { /* figurine; otherwise spell */
- int mndx = otmp->corpsenm;
- + if (idol) {
- + mndx = ndemon(A_NONE);
- + if (mndx == NON_PM) /* just in case */
- + continue;
- + }
- pm = &mons[mndx];
- /* activating a figurine provides one way to exceed the
- @@ -86,10 +92,14 @@ boolean quietly;
- it has a special limit (erinys, Nazgul) */
- if ((mvitals[mndx].mvflags & G_EXTINCT)
- && mbirth_limit(mndx) != MAXMONNO) {
- - if (!quietly)
- + if (!quietly) {
- /* have just been given "You <do something with>
- the figurine and it transforms." message */
- - pline("... into a pile of dust.");
- + if (!idol)
- + pline("... into a pile of dust.");
- + else if (!Blind)
- + pline_The("cloud disperses.");
- + }
- break; /* mtmp is null */
- }
- } else if (!rn2(3)) {
- @@ -103,10 +113,16 @@ boolean quietly;
- }
- }
- - mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
- + mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER
- + | (!idol * NO_MINVENT));
- if (otmp && !mtmp) { /* monster was genocided or square occupied */
- - if (!quietly)
- - pline_The("figurine writhes and then shatters into pieces!");
- + if (!quietly) {
- + if (!idol)
- + pline_The("figurine writhes and then shatters "
- + "into pieces!");
- + else if (!Blind)
- + pline_The("cloud disperses.");
- + }
- break;
- }
- } while (!mtmp && --trycnt > 0);
- @@ -114,6 +130,14 @@ boolean quietly;
- if (!mtmp)
- return (struct monst *) 0;
- + if (idol && !quietly && !Blind) {
- + pline_The("mist coagulates into the shape of %s%s.",
- + x_monnam(mtmp, ARTICLE_A, (char *) 0, SUPPRESS_IT
- + | SUPPRESS_INVISIBLE | SUPPRESS_SADDLE
- + | SUPPRESS_NAME, FALSE),
- + canspotmon(mtmp) ? "" : " and vanishes");
- + }
- +
- if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
- return (struct monst *) 0;
- @@ -134,7 +158,7 @@ boolean quietly;
- }
- }
- /* if figurine has been named, give same name to the monster */
- - if (has_oname(otmp))
- + if (has_oname(otmp) && !idol)
- mtmp = christen_monst(mtmp, ONAME(otmp));
- }
- set_malign(mtmp); /* more alignment changes */
- @@ -551,6 +575,19 @@ long nmv; /* number of moves */
- m_unleash(mtmp, FALSE);
- }
- + /* maybe pick up the abandoned Amulet */
- + if (mtmp->data == &mons[PM_AGENT] && !mtmp->mpeaceful
- + && rn2(imv + 1) > 300) {
- + struct obj *otmp;
- + for (otmp = level.objlist; otmp; otmp = otmp->nobj)
- + if (otmp->otyp == AMULET_OF_YENDOR
- + || otmp->otyp == FAKE_AMULET_OF_YENDOR) {
- + obj_extract_self(otmp);
- + (void) mpickobj(mtmp, otmp);
- + break;
- + }
- + }
- +
- /* recover lost hit points */
- if (!regenerates(mtmp->data))
- imv /= 20;
- @@ -923,7 +960,7 @@ register struct obj *obj;
- /* monsters with conflicting structures cannot be tamed */
- || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
- || is_covetous(mtmp->data) || is_human(mtmp->data)
- - || (is_demon(mtmp->data) && !is_demon(youmonst.data))
- + || (is_demon(mtmp->data) && !is_demon(raceptr(&youmonst)))
- || (obj && dogfood(mtmp, obj) >= MANFOOD))
- return FALSE;
- diff --git c/src/dothrow.c w/src/dothrow.c
- index c1a415a..e0a6db4 100644
- --- c/src/dothrow.c
- +++ w/src/dothrow.c
- @@ -115,6 +115,7 @@ int shotlimit;
- /* some roles don't get a volley bonus until becoming expert */
- weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_PRIEST)
- || (Role_if(PM_HEALER) && skill != P_KNIFE)
- + || (Role_if(PM_INFIDEL) && skill != P_DAGGER)
- || (Role_if(PM_TOURIST) && skill != -P_DART)
- /* poor dexterity also inhibits multishot */
- || Fumbling || ACURR(A_DEX) <= 6);
- diff --git c/src/dungeon.c w/src/dungeon.c
- index 27b7481..1eedd62 100644
- --- c/src/dungeon.c
- +++ w/src/dungeon.c
- @@ -1173,7 +1173,8 @@ boolean at_stairs;
- /* Taking an up dungeon branch. */
- /* KMH -- Upwards branches are okay if not level 1 */
- /* (Just make sure it doesn't go above depth 1) */
- - if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet)
- + if (!u.uz.dnum && u.uz.dlevel == 1
- + && !(u.uhave.amulet && u.uachieve.amulet))
- done(ESCAPED);
- else
- goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
- @@ -2998,8 +2999,11 @@ boolean printdun;
- else
- ADDNTOBUF("temple", mptr->feat.ntemple);
- - /* only print out altar's god if they are all to your god */
- - if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
- + /* only print out altar's god if they are all to your god
- + * For Infidels, only print Moloch if there's exactly one altar;
- + * this is a technical resriction (i.e. I'm too lazy to fix it) */
- + if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type
- + && (u.ualign.type != A_NONE || mptr->feat.naltar == 1))
- Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
- }
- ADDNTOBUF("throne", mptr->feat.nthrone);
- diff --git c/src/eat.c w/src/eat.c
- index 5e2aa1a..8ca11ae 100644
- --- c/src/eat.c
- +++ w/src/eat.c
- @@ -2797,10 +2797,7 @@ gethungry()
- will need to wear an Amulet of Unchanging so still burn a small
- amount of nutrition in the 'moves % 20' ring/amulet check below */
- if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
- - && (carnivorous(youmonst.data)
- - || herbivorous(youmonst.data)
- - || metallivorous(youmonst.data))
- - && !Slow_digestion)
- + && !inediate(raceptr(&youmonst)) && !Slow_digestion)
- u.uhunger--; /* ordinary food consumption */
- if (moves % 2) { /* odd turns */
- diff --git c/src/end.c w/src/end.c
- index 4df88ce..a63ea9f 100644
- --- c/src/end.c
- +++ w/src/end.c
- @@ -925,6 +925,8 @@ struct obj *list; /* inventory or container contents */
- } else if (obj->oartifact) {
- continue;
- } else if (obj->oclass == AMULET_CLASS) {
- + if (Role_if(PM_INFIDEL) && obj->otyp == AMULET_OF_YENDOR)
- + continue; /* starting inventory */
- i = obj->otyp - FIRST_AMULET;
- if (!amulets[i].count) {
- amulets[i].count = obj->quan;
- @@ -1478,7 +1480,9 @@ int how;
- ? (const char *) ((flags.female && urole.name.f)
- ? urole.name.f
- : urole.name.m)
- - : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
- + : Role_if(PM_INFIDEL) /* can only ascend via Moloch */
- + ? (const char *) (flags.female ? "Demon Lady" : "Demon Lord")
- + : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
- dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
- dump_forward_putstr(endwin, 0, "", done_stopprint);
- diff --git c/src/engrave.c w/src/engrave.c
- index b001855..975b538 100644
- --- c/src/engrave.c
- +++ w/src/engrave.c
- @@ -431,7 +431,8 @@ int
- freehand()
- {
- return (!uwep || !welded(uwep)
- - || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
- + || (!bimanual(uwep)
- + && (!uarms || !cursed(uarms, TRUE))));
- }
- static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
- @@ -504,7 +505,7 @@ doengrave()
- maxelen = BUFSZ - 1;
- if (oep)
- oetype = oep->engr_type;
- - if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
- + if (is_demon(raceptr(&youmonst)) || youmonst.data->mlet == S_VAMPIRE)
- type = ENGR_BLOOD;
- /* Can the adventurer engrave at all? */
- diff --git c/src/exper.c w/src/exper.c
- index 9b96b5c..fc4cf1e 100644
- --- c/src/exper.c
- +++ w/src/exper.c
- @@ -32,6 +32,7 @@ int en;
- case PM_WIZARD:
- return (2 * en);
- case PM_HEALER:
- + case PM_INFIDEL:
- case PM_KNIGHT:
- return ((3 * en) / 2);
- case PM_BARBARIAN:
- diff --git c/src/explode.c w/src/explode.c
- index 31ba7c7..3f933b1 100644
- --- c/src/explode.c
- +++ w/src/explode.c
- @@ -185,7 +185,7 @@ int expltype;
- case AD_DISN:
- explmask[i][j] = (olet == WAND_CLASS)
- ? !!(nonliving(youmonst.data)
- - || is_demon(youmonst.data))
- + || is_demon(raceptr(&youmonst)))
- : !!Disint_resistance;
- break;
- case AD_ELEC:
- diff --git c/src/hack.c w/src/hack.c
- index 79fe740..da4bd69 100644
- --- c/src/hack.c
- +++ w/src/hack.c
- @@ -2012,7 +2012,7 @@ invocation_message()
- Sprintf(buf, "under your %s", makeplural(body_part(FOOT)));
- You_feel("a strange vibration %s.", buf);
- - u.uevent.uvibrated = 1;
- + u.uachieve.vibrating_square = 1;
- if (otmp && otmp->spe == 7 && otmp->lamplit)
- pline("%s %s!", The(xname(otmp)),
- Blind ? "throbs palpably" : "glows with a strange light");
- @@ -2053,7 +2053,7 @@ switch_terrain()
- /* [minor bug: we don't know whether this is beginning flight or
- resuming it; that could be tracked so that this message could
- be adjusted to "resume flying", but isn't worth the effort...] */
- - if (Flying)
- + if (Flying && !was_flying)
- You("start flying.");
- }
- if ((!Levitation ^ was_levitating) || (!Flying ^ was_flying))
- diff --git c/src/invent.c w/src/invent.c
- index 7e7e3b2..c0b87c1 100644
- --- c/src/invent.c
- +++ w/src/invent.c
- @@ -813,7 +813,8 @@ struct obj *obj;
- if (u.uhave.amulet)
- impossible("already have amulet?");
- u.uhave.amulet = 1;
- - u.uachieve.amulet = 1;
- + if (!Role_if(PM_INFIDEL))
- + u.uachieve.amulet = 1;
- } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
- if (u.uhave.menorah)
- impossible("already have candelabrum?");
- @@ -834,6 +835,8 @@ struct obj *obj;
- if (u.uhave.questart)
- impossible("already have quest artifact?");
- u.uhave.questart = 1;
- + if (Role_if(PM_INFIDEL) && obj->spe)
- + u.uhave.amulet = 1;
- artitouch(obj);
- }
- set_artifact_intrinsic(obj, 1, W_ART);
- @@ -1132,6 +1135,8 @@ struct obj *obj;
- if (!u.uhave.questart)
- impossible("don't have quest artifact?");
- u.uhave.questart = 0;
- + if (Role_if(PM_INFIDEL) && obj->spe)
- + u.uhave.amulet = 0;
- }
- set_artifact_intrinsic(obj, 0, W_ART);
- }
- @@ -1181,6 +1186,7 @@ register struct obj *obj;
- boolean update_map;
- if (obj->otyp == AMULET_OF_YENDOR
- + || Role_if(PM_INFIDEL) && is_quest_artifact(obj) && obj->spe
- || obj->otyp == CANDELABRUM_OF_INVOCATION
- || obj->otyp == BELL_OF_OPENING
- || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- @@ -1601,10 +1607,11 @@ register const char *let, *word;
- || (!strncmp(word, "rub on the stone", 16)
- && *let == GEM_CLASS && otmp->dknown
- && objects[otyp].oc_name_known)
- - /* suppress corpses on astral, amulets elsewhere */
- + /* suppress corpses on astral (or sanctum), amulets elsewhere */
- || (!strcmp(word, "sacrifice")
- /* (!astral && amulet) || (astral && !amulet) */
- - && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
- + && ((!Is_astralevel(&u.uz) && !Is_sanctum(&u.uz))
- + ^ (otmp->oclass != AMULET_CLASS)))
- /* suppress container being stashed into */
- || (!strcmp(word, "stash") && !ck_bag(otmp))
- /* worn armor (shirt, suit) covered by worn armor (suit, cloak)
- diff --git c/src/makemon.c w/src/makemon.c
- index 3145ad6..271806a 100644
- --- c/src/makemon.c
- +++ w/src/makemon.c
- @@ -185,7 +185,7 @@ register struct monst *mtmp;
- (void) mongets(mtmp, (mm != PM_ETTIN) ? BOULDER : CLUB);
- break;
- case S_HUMAN:
- - if (is_mercenary(ptr)) {
- + if (is_mercenary(ptr) || mm == PM_TEMPLAR) {
- w1 = w2 = 0;
- switch (mm) {
- case PM_WATCHMAN:
- @@ -204,6 +204,7 @@ register struct monst *mtmp;
- break;
- case PM_CAPTAIN:
- case PM_WATCH_CAPTAIN:
- + case PM_TEMPLAR:
- w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
- break;
- default:
- @@ -266,11 +267,20 @@ register struct monst *mtmp;
- } else if (mm == PM_NINJA) { /* extra quest villains */
- (void) mongets(mtmp, rn2(4) ? SHURIKEN : DART);
- (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE);
- + } else if (mm == PM_CHAMPION) {
- + (void) mongets(mtmp, rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE);
- + (void) mongets(mtmp, rn2(3) ? RING_MAIL : CHAIN_MAIL);
- + } else if (mm == PM_AGENT) {
- + (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : DAGGER);
- + if (!rn2(3))
- + (void) mongets(mtmp, LEATHER_ARMOR);
- + (void) mongets(mtmp, POT_INVISIBILITY);
- } else if (ptr->msound == MS_GUARDIAN) {
- /* quest "guardians" */
- switch (mm) {
- case PM_STUDENT:
- case PM_ATTENDANT:
- + case PM_CULTIST:
- case PM_ABBOT:
- case PM_ACOLYTE:
- case PM_GUIDE:
- @@ -588,7 +598,7 @@ register struct monst *mtmp;
- */
- switch (ptr->mlet) {
- case S_HUMAN:
- - if (is_mercenary(ptr)) {
- + if (is_mercenary(ptr) || monsndx(ptr) == PM_TEMPLAR) {
- register int mac;
- switch (monsndx(ptr)) {
- @@ -613,6 +623,9 @@ register struct monst *mtmp;
- case PM_WATCH_CAPTAIN:
- mac = -2;
- break;
- + case PM_TEMPLAR:
- + mac = -3;
- + break;
- default:
- impossible("odd mercenary %d?", monsndx(ptr));
- mac = 0;
- @@ -655,6 +668,10 @@ register struct monst *mtmp;
- } else if (ptr == &mons[PM_WATCHMAN]) {
- if (rn2(3)) /* most watchmen carry a whistle */
- (void) mongets(mtmp, TIN_WHISTLE);
- + } else if (ptr == &mons[PM_TEMPLAR]) {
- + if (rn2(3)) /* being in a holy order has its benefits */
- + (void) mongets(mtmp, rn2(4) ? POT_HEALING
- + : POT_EXTRA_HEALING);
- } else if (ptr == &mons[PM_GUARD]) {
- /* if hero teleports out of a vault while being confronted
- by the vault's guard, there is a shrill whistling sound,
- @@ -695,6 +712,22 @@ register struct monst *mtmp;
- mkmonmoney(mtmp, (long) rn1(10, 20));
- } else if (quest_mon_represents_role(ptr, PM_MONK)) {
- (void) mongets(mtmp, rn2(11) ? ROBE : CLOAK_OF_MAGIC_RESISTANCE);
- + } else if (ptr == &mons[PM_PREACHER_OF_MOLOCH]) {
- + (void) mongets(mtmp, QUARTERSTAFF);
- + (void) mongets(mtmp, rn2(3) ? ROBE : CLOAK_OF_PROTECTION);
- + } else if (ptr == &mons[PM_PALADIN]) {
- + otmp = mksobj(MORNING_STAR, FALSE, FALSE);
- + otmp->blessed = otmp->oerodeproof = 1;
- + otmp->spe = rn1(3, 3);
- + (void) mpickobj(mtmp, otmp);
- + /* the Paladin wears no helmet
- + * because she looks cooler without a helmet */
- + (void) mongets(mtmp, LEATHER_GLOVES);
- + (void) mongets(mtmp, SHIELD_OF_REFLECTION);
- + (void) mongets(mtmp, LEATHER_CLOAK);
- + (void) mongets(mtmp, CRYSTAL_PLATE_MAIL);
- + (void) mongets(mtmp, HIGH_BOOTS);
- + (void) mongets(mtmp, POT_SPEED);
- }
- break;
- case S_NYMPH:
- @@ -1269,7 +1302,7 @@ int mmflags;
- mtmp->mpeaceful = FALSE;
- break;
- case S_UNICORN:
- - if (is_unicorn(ptr) && sgn(u.ualign.type) == sgn(ptr->maligntyp))
- + if (is_unicorn(ptr) && u.ualign.type == sgn(ptr->maligntyp))
- mtmp->mpeaceful = TRUE;
- break;
- case S_BAT:
- @@ -1365,6 +1398,13 @@ int mmflags;
- ? !eminp->renegade
- : eminp->renegade;
- }
- + /* these monsters are normally affiliated with a deity */
- + if ((mndx == PM_PALADIN || mndx == PM_TEMPLAR || mndx == PM_CHAMPION
- + || mndx == PM_AGENT) && !(mmflags & MM_EMIN)) {
- + newemin(mtmp);
- + mtmp->isminion = 1;
- + EMIN(mtmp)->min_align = sgn(ptr->maligntyp);
- + }
- set_malign(mtmp); /* having finished peaceful changes */
- if (anymon && !(mmflags & MM_NOGRP)) {
- if ((ptr->geno & G_SGROUP) && rn2(2)) {
- @@ -2007,7 +2047,11 @@ register struct permonst *ptr;
- if (always_peaceful(ptr))
- return TRUE;
- - if (always_hostile(ptr))
- + /* Major demons will sometimes be peaceful to unaligned Infidels.
- + * They must pass this 50% check, then the 50% check for chaotics
- + * being non-hostile to unaligned, then the usual check for coaligned.
- + * For crowned Infidels, the last two checks are bypassed. */
- + if (always_hostile(ptr) && (ual != A_NONE || !is_demon(ptr) || rn2(2)))
- return FALSE;
- if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN)
- return TRUE;
- @@ -2024,8 +2068,12 @@ register struct permonst *ptr;
- if (sgn(mal) != sgn(ual))
- return FALSE;
- - /* Negative monster hostile to player with Amulet. */
- - if (mal < A_NEUTRAL && u.uhave.amulet)
- + /* Not all chaotics support Moloch. This goes especially for elves. */
- + if (ual == A_NONE && (is_elf(ptr) || rn2(2)))
- + return FALSE;
- +
- + /* Chaotic monsters hostile to players with Amulet, except Infidels. */
- + if (mal < A_NEUTRAL && u.uhave.amulet && ual != A_NONE)
- return FALSE;
- /* minions are hostile to players that have strayed at all */
- @@ -2070,7 +2118,7 @@ struct monst *mtmp;
- mal *= 5;
- }
- - coaligned = (sgn(mal) == sgn(u.ualign.type));
- + coaligned = (sgn(mal) == u.ualign.type);
- if (mtmp->data->msound == MS_LEADER) {
- mtmp->malign = -20;
- } else if (mal == A_NONE) {
- @@ -2078,6 +2126,8 @@ struct monst *mtmp;
- mtmp->malign = 0;
- else
- mtmp->malign = 20; /* really hostile */
- + if (u.ualign.type == A_NONE)
- + mtmp->malign -= 20; /* reverse */
- } else if (always_peaceful(mtmp->data)) {
- int absmal = abs(mal);
- if (mtmp->mpeaceful)
- diff --git c/src/mcastu.c w/src/mcastu.c
- index 1b2fb63..3c1402a 100644
- --- c/src/mcastu.c
- +++ w/src/mcastu.c
- @@ -377,7 +377,7 @@ int spellnum;
- switch (spellnum) {
- case MGC_DEATH_TOUCH:
- pline("Oh no, %s's using the touch of death!", mhe(mtmp));
- - if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
- + if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
- You("seem no deader than before.");
- } else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
- if (Hallucination) {
- diff --git c/src/mhitu.c w/src/mhitu.c
- index 849ddb1..cbb24de 100644
- --- c/src/mhitu.c
- +++ w/src/mhitu.c
- @@ -589,7 +589,7 @@ register struct monst *mtmp;
- /* Special demon handling code */
- if ((mtmp->cham == NON_PM) && is_demon(mdat) && !range2
- && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS]
- - && mtmp->data != &mons[PM_INCUBUS])
- + && mtmp->data != &mons[PM_INCUBUS] && mtmp->data != &mons[PM_DEMON])
- if (!mtmp->mcan && !rn2(13))
- (void) msummon(mtmp);
- diff --git c/src/minion.c w/src/minion.c
- index 4277b45..5624a22 100644
- --- c/src/minion.c
- +++ w/src/minion.c
- @@ -261,7 +261,7 @@ register struct monst *mtmp;
- }
- newsym(mtmp->mx, mtmp->my);
- }
- - if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
- + if (is_demon(raceptr(&youmonst))) { /* Won't blackmail their own. */
- if (!Deaf)
- pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
- flags.female ? "Sister" : "Brother");
- diff --git c/src/mon.c w/src/mon.c
- index 4f0a13d..7d85d8b 100644
- --- c/src/mon.c
- +++ w/src/mon.c
- @@ -2472,7 +2472,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
- }
- if ((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)
- change_luck(-1);
- - if (is_unicorn(mdat) && sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
- + if (is_unicorn(mdat) && u.ualign.type == sgn(mdat->maligntyp)) {
- change_luck(-5);
- You_feel("guilty...");
- }
- @@ -2500,7 +2500,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
- /* cancel divine protection for killing your priest */
- if (p_coaligned(mtmp))
- u.ublessed = 0;
- - if (mdat->maligntyp == A_NONE)
- + else if (mdat->maligntyp == A_NONE)
- adjalign((int) (ALIGNLIM / 4)); /* BIG bonus */
- } else if (mtmp->mtame) {
- adjalign(-15); /* bad!! */
- @@ -2905,7 +2905,8 @@ boolean via_attack;
- it's intentionally larger than the 1s and 2s that are normally
- given for this sort of thing. */
- /* reduce to 3 (average) when alignment is already very low */
- - adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
- + if (u.ualign.type != A_NONE)
- + adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
- if (!Blind)
- pline("The engraving beneath you fades.");
- diff --git c/src/mondata.c w/src/mondata.c
- index fae34e8..7d20930 100644
- --- c/src/mondata.c
- +++ w/src/mondata.c
- @@ -97,7 +97,7 @@ boolean
- resists_drli(mon)
- struct monst *mon;
- {
- - struct permonst *ptr = mon->data;
- + struct permonst *ptr = raceptr(mon); /* handle demonic race */
- struct obj *wep;
- if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
- @@ -421,8 +421,7 @@ register struct permonst *ptr;
- return (boolean) (bigmonst(ptr)
- || (ptr->msize > MZ_SMALL && !humanoid(ptr))
- /* special cases of humanoids that cannot wear suits */
- - || ptr == &mons[PM_MARILITH]
- - || ptr == &mons[PM_WINGED_GARGOYLE]);
- + || ptr == &mons[PM_MARILITH]);
- }
- /* creature sticks other creatures it hits */
- @@ -1077,7 +1076,7 @@ int montyp1, montyp2;
- * Returns correct pointer for non-polymorphed and polymorphed
- * player. It does not return a pointer to player role character.
- */
- -const struct permonst *
- +struct permonst *
- raceptr(mtmp)
- struct monst *mtmp;
- {
- diff --git c/src/monmove.c w/src/monmove.c
- index cd6ca98..9abc779 100644
- --- c/src/monmove.c
- +++ w/src/monmove.c
- @@ -344,6 +344,14 @@ int *inrange, *nearby, *scared;
- || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
- *scared = 1;
- monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
- + if (u.ualign.type == A_NONE && !context.coward
- + && sengr_at("Elbereth", seescaryx, seescaryy, TRUE)) {
- + /* Followers of Moloch aren't supposed
- + * to hide behind other gods. */
- + You_feel("like a coward.");
- + context.coward = TRUE; /* once per move */
- + adjalign(-5);
- + }
- } else
- *scared = 0;
- }
- @@ -927,6 +935,9 @@ register int after;
- > ((ygold = findgold(invent)) ? ygold->quan : 0L))))
- appr = -1;
- + if (monsndx(ptr) == PM_AGENT && mon_has_amulet(mtmp))
- + appr = -1; /* objective secured, retreat */
- +
- if (!should_see && can_track(ptr)) {
- register coord *cp;
- diff --git c/src/monst.c w/src/monst.c
- index 6b8a5f7..de919f5 100644
- --- c/src/monst.c
- +++ w/src/monst.c
- @@ -2139,6 +2139,27 @@ struct permonst _mons2[] = {
- M1_HUMANOID | M1_POIS | M1_REGEN | M1_OMNIVORE,
- M2_NOPOLY | M2_WERE | M2_HOSTILE | M2_HUMAN | M2_COLLECT,
- M3_INFRAVISIBLE, 6, CLR_ORANGE),
- + /* Only generated when playing as Infidel.
- + * Has emin, so always appears as a "champion of [deity]".
- + * Note: the difficulty is purposefully lowered. */
- + MON("champion", S_HUMAN, LVL(12, 12, 6, 10, 0), (G_NOGEN | G_NOHELL | 2),
- + A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK,
- + NO_ATTK, NO_ATTK, NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0,
- + M1_HUMANOID | M1_OMNIVORE,
- + M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_NASTY | M2_STRONG | M2_COLLECT,
- + M3_INFRAVISIBLE, 6, CLR_GRAY),
- + /* Only generated when playing as Infidel.
- + * Has emin, so always appears as an "agent of [deity]".
- + * Note: the difficulty is purposefully lowered. */
- + MON("agent", S_HUMAN, LVL(6, 18, 10, 10, -7), (G_NOGEN | G_NOHELL | 3),
- + A(ATTK(AT_WEAP, AD_SAMU, 1, 4), ATTK(AT_CLAW, AD_SAMU, 1, 1),
- + ATTK(AT_CLAW, AD_SAMU, 1, 1), ATTK(AT_CLAW, AD_SAMU, 1, 1),
- + NO_ATTK, NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
- + M1_HUMANOID | M1_OMNIVORE | M1_TPORT,
- + M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STALK | M2_STRONG | M2_COLLECT,
- + M3_INFRAVISIBLE, 6, CLR_BLACK),
- MON("elf", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN, /* for corpses */
- A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
- NO_ATTK),
- @@ -2607,6 +2628,14 @@ struct permonst _mons2[] = {
- SIZ(1500, 400, MS_DJINNI, MZ_HUMAN), MR_POISON | MR_STONE, 0,
- M1_HUMANOID | M1_FLY | M1_POIS, M2_NOPOLY | M2_STALK | M2_COLLECT,
- M3_INFRAVISIBLE, 8, CLR_YELLOW),
- + /* racial monster for crowned Infidels */
- + MON("demon", S_DEMON, LVL(10, 12, 10, 10, A_NONE), (G_NOGEN | G_NOCORPSE),
- + A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_STNG, AD_DRST, 2, 4),
- + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_GRUNT, MZ_HUMAN), MR_FIRE | MR_POISON, 0,
- + M1_HUMANOID | M1_FLY | M1_SEE_INVIS | M1_POIS,
- + M2_NOPOLY | M2_DEMON | M2_STALK | M2_HOSTILE | M2_COLLECT,
- + M3_INFRAVISIBLE | M3_INFRAVISION, 13, CLR_RED),
- /*
- * sea monsters
- */
- @@ -2757,6 +2786,13 @@ struct permonst _mons2[] = {
- M1_HUMANOID | M1_OMNIVORE,
- M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
- 12, HI_DOMESTIC),
- + MON("infidel", S_HUMAN, LVL(10, 12, 10, 2, A_NONE), G_NOGEN,
- + A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
- + NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_FIRE, 0,
- + M1_HUMANOID | M1_OMNIVORE,
- + M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
- + 12, HI_DOMESTIC),
- MON("knight", S_HUMAN, LVL(10, 12, 10, 1, 3), G_NOGEN,
- A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
- NO_ATTK, NO_ATTK, NO_ATTK),
- @@ -2884,6 +2920,17 @@ struct permonst _mons2[] = {
- M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
- | M2_COLLECT | M2_MAGIC,
- M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
- + /* apparently she should be a "preacheress" if female,
- + * but that word just sounds silly, imo */
- + MON("preacher of Moloch", S_HUMAN, LVL(20, 12, 0, 40, A_NONE),
- + (G_NOGEN | G_UNIQ),
- + A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK,
- + NO_ATTK, NO_ATTK, NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_FIRE | MR_ELEC, 0,
- + M1_HUMANOID | M1_OMNIVORE,
- + M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT
- + | M2_MAGIC,
- + M3_CLOSE | M3_INFRAVISIBLE, 23, CLR_RED),
- MON("King Arthur", S_HUMAN, LVL(20, 12, 0, 40, 20), (G_NOGEN | G_UNIQ),
- A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
- NO_ATTK, NO_ATTK, NO_ATTK),
- @@ -3026,6 +3073,18 @@ struct permonst _mons2[] = {
- | M2_HOSTILE | M2_NASTY | M2_MALE | M2_JEWELS | M2_COLLECT,
- M3_WANTSARTI | M3_WAITFORU | M3_INFRAVISION | M3_INFRAVISIBLE,
- 23, CLR_GRAY),
- + /* Has emin, so always appears as the "Paladin of [deity]". */
- + MON("Paladin", S_HUMAN, LVL(24, 12, 0, 50, 20),
- + (G_NOGEN | G_UNIQ | G_NOCORPSE),
- + A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_STUN, 2, 6),
- + ATTK(AT_MAGC, AD_CLRC, 1, 8), ATTK(AT_CLAW, AD_SAMU, 1, 6),
- + NO_ATTK, NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_NEMESIS, MZ_HUMAN), MR_POISON | MR_STONE, 0,
- + M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS,
- + M2_NOPOLY | M2_HUMAN | M2_MINION | M2_LORD | M2_STRONG | M2_FEMALE
- + | M2_STALK | M2_HOSTILE | M2_NASTY | M2_COLLECT | M2_MAGIC,
- + M3_WANTSARTI | M3_WANTSAMUL | M3_WAITFORU | M3_INFRAVISIBLE,
- + 29, HI_GOLD),
- MON("Ixoth", S_DRAGON, LVL(15, 12, -1, 20, -14), (G_NOGEN | G_UNIQ),
- A(ATTK(AT_BREA, AD_FIRE, 8, 6), ATTK(AT_BITE, AD_PHYS, 4, 8),
- ATTK(AT_MAGC, AD_SPEL, 0, 0), ATTK(AT_CLAW, AD_PHYS, 2, 4),
- @@ -3148,6 +3207,21 @@ struct permonst _mons2[] = {
- M1_HUMANOID | M1_OMNIVORE,
- M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
- M3_INFRAVISIBLE, 7, HI_DOMESTIC),
- + /* Has emin, so always appears as a "templar of [deity]". */
- + MON("templar", S_HUMAN, LVL(12, 10, 10, 20, 10), G_NOGEN,
- + A(ATTK(AT_WEAP, AD_PHYS, 3, 4), ATTK(AT_WEAP, AD_PHYS, 3, 4), NO_ATTK,
- + NO_ATTK, NO_ATTK, NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
- + M1_HUMANOID | M1_OMNIVORE,
- + M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STRONG | M2_COLLECT,
- + M3_INFRAVISIBLE, 14, CLR_BLUE),
- + MON("cultist", S_HUMAN, LVL(5, 12, 10, 10, A_NONE), G_NOGEN,
- + A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
- + NO_ATTK),
- + SIZ(WT_HUMAN, 400, MS_GUARDIAN, MZ_HUMAN), MR_FIRE, 0,
- + M1_HUMANOID | M1_OMNIVORE,
- + M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
- + M3_INFRAVISIBLE, 7, HI_DOMESTIC),
- MON("page", S_HUMAN, LVL(5, 12, 10, 10, 3), G_NOGEN,
- A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
- NO_ATTK, NO_ATTK, NO_ATTK),
- diff --git c/src/mplayer.c w/src/mplayer.c
- index 2dba08e..b65f708 100644
- --- c/src/mplayer.c
- +++ w/src/mplayer.c
- @@ -195,6 +195,16 @@ register boolean special;
- if (rn2(2))
- shield = STRANGE_OBJECT;
- break;
- + case PM_INFIDEL:
- + if (!rn2(4))
- + weapon = CRYSKNIFE;
- + if (rn2(3))
- + cloak = CLOAK_OF_PROTECTION;
- + if (rn2(4))
- + helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
- + if (rn2(2))
- + shield = STRANGE_OBJECT;
- + break;
- case PM_KNIGHT:
- if (rn2(4))
- weapon = LONG_SWORD;
- diff --git c/src/muse.c w/src/muse.c
- index 2dfb92f..6062690 100644
- --- c/src/muse.c
- +++ w/src/muse.c
- @@ -2091,6 +2091,9 @@ struct obj *obj;
- return (boolean) !(nonliving(mon->data) || is_vampshifter(mon));
- if (typ == AMULET_OF_REFLECTION)
- return TRUE;
- + if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
- + return (boolean) (mon->data == &mons[PM_AGENT]
- + && !mon_has_amulet(mon));
- break;
- case TOOL_CLASS:
- if (typ == PICK_AXE)
- diff --git c/src/pickup.c w/src/pickup.c
- index 76f35aa..21133f5 100644
- --- c/src/pickup.c
- +++ w/src/pickup.c
- @@ -2150,6 +2150,7 @@ register struct obj *obj;
- pline_The("stone%s won't leave your person.", plur(obj->quan));
- return 0;
- } else if (obj->otyp == AMULET_OF_YENDOR
- + || Role_if(PM_INFIDEL) && is_quest_artifact(obj) && obj->spe
- || obj->otyp == CANDELABRUM_OF_INVOCATION
- || obj->otyp == BELL_OF_OPENING
- || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
- diff --git c/src/polyself.c w/src/polyself.c
- index b053091..7fa7e3f 100644
- --- c/src/polyself.c
- +++ w/src/polyself.c
- @@ -42,8 +42,10 @@ void
- set_uasmon()
- {
- struct permonst *mdat = &mons[u.umonnum];
- + struct permonst *racedat; /* for infravision, flying */
- set_mon_data(&youmonst, mdat);
- + racedat = raceptr(&youmonst);
- #define PROPSET(PropIndx, ON) \
- do { \
- @@ -81,7 +83,7 @@ set_uasmon()
- PROPSET(SEE_INVIS, perceives(mdat));
- PROPSET(TELEPAT, telepathic(mdat));
- /* note that Infravision uses mons[race] rather than usual mons[role] */
- - PROPSET(INFRAVISION, infravision(Upolyd ? mdat : &mons[urace.malenum]));
- + PROPSET(INFRAVISION, infravision(racedat));
- PROPSET(INVIS, pm_invisible(mdat));
- PROPSET(TELEPORT, can_teleport(mdat));
- PROPSET(TELEPORT_CONTROL, control_teleport(mdat));
- @@ -89,7 +91,9 @@ set_uasmon()
- /* floating eye is the only 'floater'; it is also flagged as a 'flyer';
- suppress flying for it so that enlightenment doesn't confusingly
- show latent flight capability always blocked by levitation */
- - PROPSET(FLYING, (is_flyer(mdat) && !is_floater(mdat)));
- + /* this property also checks race instead of role */
- + PROPSET(FLYING, (is_flyer(racedat) && !is_floater(racedat)));
- + check_wings(TRUE);
- PROPSET(SWIMMING, is_swimmer(mdat));
- /* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless
- key off of it but include different monster forms...] */
- diff --git c/src/potion.c w/src/potion.c
- index c6dffc5..fe19946 100644
- --- c/src/potion.c
- +++ w/src/potion.c
- @@ -648,8 +648,9 @@ register struct obj *otmp;
- break;
- }
- unkn++;
- - if (is_undead(youmonst.data) || is_demon(youmonst.data)
- - || u.ualign.type == A_CHAOTIC) {
- + if (is_undead(youmonst.data) || is_demon(raceptr(&youmonst))
- + || u.ualign.type <= A_CHAOTIC) {
- + int dice = (u.ualign.type == A_NONE) ? 4 : 2;
- if (otmp->blessed) {
- pline("This burns like %s!", hliquid("acid"));
- exercise(A_CON, FALSE);
- @@ -660,11 +661,11 @@ register struct obj *otmp;
- you_unwere(FALSE);
- set_ulycn(NON_PM); /* cure lycanthropy */
- }
- - losehp(Maybe_Half_Phys(d(2, 6)), "potion of holy water",
- + losehp(Maybe_Half_Phys(d(dice, 6)), "potion of holy water",
- KILLED_BY_AN);
- } else if (otmp->cursed) {
- You_feel("quite proud of yourself.");
- - healup(d(2, 6), 0, 0, 0);
- + healup(d(dice, 6), 0, 0, 0);
- if (u.ulycn >= LOW_PM && !Upolyd)
- you_were();
- exercise(A_CON, TRUE);
- diff --git c/src/pray.c w/src/pray.c
- index 79369fc..d6bdf22 100644
- --- c/src/pray.c
- +++ w/src/pray.c
- @@ -3,6 +3,7 @@
- /* NetHack may be freely redistributed. See license for details. */
- #include "hack.h"
- +#include "qtext.h"
- STATIC_PTR int NDECL(prayer_done);
- STATIC_DCL struct obj *NDECL(worst_cursed_item);
- @@ -12,8 +13,6 @@ STATIC_DCL void FDECL(angrygods, (ALIGNTYP_P));
- STATIC_DCL void FDECL(at_your_feet, (const char *));
- STATIC_DCL void NDECL(gcrownu);
- STATIC_DCL void FDECL(pleased, (ALIGNTYP_P));
- -STATIC_DCL void FDECL(godvoice, (ALIGNTYP_P, const char *));
- -STATIC_DCL void FDECL(god_zaps_you, (ALIGNTYP_P));
- STATIC_DCL void FDECL(fry_by_god, (ALIGNTYP_P, BOOLEAN_P));
- STATIC_DCL void FDECL(gods_angry, (ALIGNTYP_P));
- STATIC_DCL void FDECL(gods_upset, (ALIGNTYP_P));
- @@ -22,7 +21,8 @@ STATIC_DCL boolean FDECL(water_prayer, (BOOLEAN_P));
- STATIC_DCL boolean FDECL(blocked_boulder, (int, int));
- /* simplify a few tests */
- -#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) && (obj)->cursed)
- +#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) \
- + && cursed(obj, TRUE))
- /*
- * Logic behind deities and altars and such:
- @@ -50,7 +50,7 @@ static const char *godvoices[] = {
- /* values calculated when prayer starts, and used when completed */
- static aligntyp p_aligntyp;
- static int p_trouble;
- -static int p_type; /* (-1)-3: (-1)=really naughty, 3=really good */
- +static int p_type; /* (-2)-3: (-1)=really naughty, 3=really good */
- #define PIOUS 20
- #define DEVOUT 14
- @@ -221,10 +221,11 @@ in_trouble()
- if (welded(uwep))
- return TROUBLE_UNUSEABLE_HANDS;
- if (Upolyd && nohands(youmonst.data)
- - && (!Unchanging || ((otmp = unchanger()) != 0 && otmp->cursed)))
- + && (!Unchanging || ((otmp = unchanger()) != 0
- + && cursed(otmp, TRUE))))
- return TROUBLE_UNUSEABLE_HANDS;
- }
- - if (Blindfolded && ublindf->cursed)
- + if (Blindfolded && cursed(ublindf, TRUE))
- return TROUBLE_CURSED_BLINDFOLD;
- /*
- @@ -274,6 +275,14 @@ worst_cursed_item()
- {
- register struct obj *otmp;
- + /* Infidels are immune to curses, but a cursed luckstone is still bad */
- + if(Role_if(PM_INFIDEL)) {
- + for (otmp = invent; otmp; otmp = otmp->nobj)
- + if (confers_luck(otmp) && otmp->cursed)
- + return otmp;
- + return (struct obj *) 0;
- + }
- +
- /* if strained or worse, check for loadstone first */
- if (near_capacity() >= HVY_ENCUMBER) {
- for (otmp = invent; otmp; otmp = otmp->nobj)
- @@ -452,7 +461,7 @@ int trouble;
- if (!Unchanging) {
- Your("shape becomes uncertain.");
- rehumanize(); /* "You return to {normal} form." */
- - } else if ((otmp = unchanger()) != 0 && otmp->cursed) {
- + } else if ((otmp = unchanger()) != 0 && cursed(otmp, TRUE)) {
- /* otmp is an amulet of unchanging */
- goto decurse;
- }
- @@ -497,7 +506,7 @@ int trouble;
- if (otmp == uarmg && Glib) {
- make_glib(0);
- Your("%s are no longer slippery.", gloves_simple_name(uarmg));
- - if (!otmp->cursed)
- + if (!cursed(otmp, TRUE))
- break;
- }
- if (!Blind || (otmp == ublindf && Blindfolded_only)) {
- @@ -578,7 +587,7 @@ int trouble;
- * bathroom walls, but who is foiled by bathrobes." --Bertrand Russell, 1943
- * Divine wrath, dungeon walls, and armor follow the same principle.
- */
- -STATIC_OVL void
- +void
- god_zaps_you(resp_god)
- aligntyp resp_god;
- {
- @@ -771,10 +780,13 @@ gcrownu()
- HSee_invisible |= FROMOUTSIDE;
- HFire_resistance |= FROMOUTSIDE;
- - HCold_resistance |= FROMOUTSIDE;
- - HShock_resistance |= FROMOUTSIDE;
- - HSleep_resistance |= FROMOUTSIDE;
- HPoison_resistance |= FROMOUTSIDE;
- + if (u.ualign.type != A_NONE) {
- + /* demons don't get all the intrinsics */
- + HCold_resistance |= FROMOUTSIDE;
- + HShock_resistance |= FROMOUTSIDE;
- + HSleep_resistance |= FROMOUTSIDE;
- + }
- godvoice(u.ualign.type, (char *) 0);
- class_gift = STRANGE_OBJECT;
- @@ -815,6 +827,17 @@ gcrownu()
- || class_gift != STRANGE_OBJECT) ? "take lives"
- : "steal souls");
- break;
- + case A_NONE:
- + u.uevent.uhand_of_elbereth = 4;
- + verbalize("I grant thee the gift of Demonhood!");
- + class_gift = SPE_FIREBALL; /* no special weapon */
- + if (Upolyd)
- + rehumanize(); /* return to human/orcish form -- not a demon yet */
- + pline1("Wings sprout from your back and you grow a barbed tail!");
- + urace = race_demon;
- + set_uasmon();
- + retouch_equipment(2); /* silver */
- + break;
- }
- if (objects[class_gift].oc_class == SPBOOK_CLASS) {
- @@ -892,6 +915,9 @@ gcrownu()
- discover_artifact(ART_STORMBRINGER);
- break;
- }
- + case A_NONE:
- + /* nothing to do */
- + break;
- default:
- obj = 0; /* lint */
- break;
- @@ -1131,6 +1157,8 @@ aligntyp g_align;
- You("are surrounded by %s aura.", an(hcolor(NH_LIGHT_BLUE)));
- for (otmp = invent; otmp; otmp = otmp->nobj) {
- if (otmp->cursed
- + /* Inf benefit from wearing cursed armor */
- + && !(Role_if(PM_INFIDEL) && (otmp->owornmask & W_ARMOR))
- && (otmp != uarmh /* [see worst_cursed_item()] */
- || uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)) {
- if (!Blind) {
- @@ -1259,7 +1287,7 @@ boolean bless_water;
- return (boolean) (changed > 0L);
- }
- -STATIC_OVL void
- +void
- godvoice(g_align, words)
- aligntyp g_align;
- const char *words;
- @@ -1357,6 +1385,9 @@ dosacrifice()
- if (otmp->otyp == CORPSE) {
- register struct permonst *ptr = &mons[otmp->corpsenm];
- struct monst *mtmp;
- + /* is this a conversion attempt? */
- + boolean to_other_god = ugod_is_angry() && !your_race(ptr)
- + && u.ualign.type != altaralign;
- /* KMH, conduct */
- u.uconduct.gnostic++;
- @@ -1367,29 +1398,45 @@ dosacrifice()
- if (rider_corpse_revival(otmp, FALSE))
- return 1;
- - if (otmp->corpsenm == PM_ACID_BLOB
- + if (otmp->corpsenm == PM_ACID_BLOB || your_race(ptr)
- || (monstermoves <= peek_at_iced_corpse_age(otmp) + 50)) {
- value = mons[otmp->corpsenm].difficulty + 1;
- + /* Not demons--no demon corpses */
- + if (is_undead(ptr) && u.ualign.type > A_CHAOTIC)
- + value += 1;
- + if (is_unicorn(ptr))
- + value += 3;
- + if (uwep && uwep->oartifact == ART_SECESPITA)
- + value += value / 2;
- if (otmp->oeaten)
- value = eaten_stat(value, otmp);
- + /* even cross-aligned sacrifices will count,
- + * as long as they're ultimately to Moloch */
- + if (u.ualign.type == A_NONE && !to_other_god) {
- + long new_timeout = moves + value * 500;
- + if (context.next_moloch_offering < new_timeout)
- + context.next_moloch_offering = new_timeout;
- + }
- }
- if (your_race(ptr)) {
- - if (is_demon(youmonst.data)) {
- + if (is_demon(raceptr(&youmonst))) {
- You("find the idea very satisfying.");
- exercise(A_WIS, TRUE);
- - } else if (u.ualign.type != A_CHAOTIC) {
- + } else if (u.ualign.type > A_CHAOTIC) {
- pline("You'll regret this infamous offense!");
- exercise(A_WIS, FALSE);
- }
- if (highaltar
- - && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)) {
- + && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)
- + && (altaralign != A_NONE || u.ualign.type != A_NONE)) {
- goto desecrate_high_altar;
- } else if (altaralign != A_CHAOTIC && altaralign != A_NONE) {
- /* curse the lawful/neutral altar */
- pline_The("altar is stained with %s blood.", urace.adj);
- - levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
- + levl[u.ux][u.uy].altarmask = u.ualign.type == A_NONE
- + ? AM_NONE : AM_CHAOTIC;
- angry_priest();
- } else {
- struct monst *dmon;
- @@ -1409,7 +1456,7 @@ dosacrifice()
- } else {
- /* either you're chaotic or altar is Moloch's or both */
- pline_The("blood covers the altar!");
- - change_luck(altaralign == A_NONE ? -2 : 2);
- + change_luck(altaralign == u.ualign.type ? 2 : -2);
- demonless_msg = "blood coagulates";
- }
- if ((pm = dlord(altaralign)) != NON_PM
- @@ -1433,7 +1480,7 @@ dosacrifice()
- pline_The("%s.", demonless_msg);
- }
- - if (u.ualign.type != A_CHAOTIC) {
- + if (u.ualign.type > A_CHAOTIC) {
- adjalign(-5);
- u.ugangr += 3;
- (void) adjattrib(A_WIS, -1, TRUE);
- @@ -1449,17 +1496,17 @@ dosacrifice()
- return 1;
- } else if (has_omonst(otmp)
- && (mtmp = get_mtraits(otmp, FALSE)) != 0
- - && mtmp->mtame) {
- + && mtmp->mtame
- + /* Moloch is OK with sacrificing pets,
- + * but make sure we're offering to him */
- + && (u.ualign.type != A_NONE || to_other_god)) {
- /* mtmp is a temporary pointer to a tame monster's attributes,
- * not a real monster */
- pline("So this is how you repay loyalty?");
- adjalign(-3);
- value = -1;
- HAggravate_monster |= FROMOUTSIDE;
- - } else if (is_undead(ptr)) { /* Not demons--no demon corpses */
- - if (u.ualign.type != A_CHAOTIC)
- - value += 1;
- - } else if (is_unicorn(ptr)) {
- + } else if (is_unicorn(ptr) && value /* fresh */) {
- int unicalign = sgn(ptr->maligntyp);
- if (unicalign == altaralign) {
- @@ -1479,7 +1526,7 @@ dosacrifice()
- else
- You_feel("you are thoroughly on the right path.");
- adjalign(5);
- - value += 3;
- + /* value += 3; -- now applied above */
- } else if (unicalign == u.ualign.type) {
- /* When sacrificing unicorn of your alignment to altar not of
- * your alignment, your god gets angry and it's a conversion.
- @@ -1491,7 +1538,7 @@ dosacrifice()
- * and different from the altar's. It's an ordinary (well,
- * with a bonus) sacrifice on a cross-aligned altar.
- */
- - value += 3;
- + /* value += 3; -- now applied above */
- }
- }
- } /* corpse */
- @@ -1499,7 +1546,7 @@ dosacrifice()
- if (otmp->otyp == AMULET_OF_YENDOR) {
- if (!highaltar) {
- too_soon:
- - if (altaralign == A_NONE && Inhell)
- + if (altaralign == A_NONE && u.ualign.type != A_NONE && Inhell)
- /* hero has left Moloch's Sanctum so is in the process
- of getting away with the Amulet (outside of Gehennom,
- fall through to the "ashamed" feedback) */
- @@ -1510,7 +1557,9 @@ dosacrifice()
- ? "homesick"
- /* if on track, give a big hint */
- : (altaralign == u.ualign.type)
- - ? "an urge to return to the surface"
- + ? (Role_if(PM_INFIDEL)
- + ? "an urge to descend deeper"
- + : "an urge to return to the surface")
- /* else headed towards celestial disgrace */
- : "ashamed");
- return 1;
- @@ -1526,6 +1575,33 @@ dosacrifice()
- You("offer the Amulet of Yendor to %s...", a_gname());
- if (altaralign == A_NONE) {
- /* Moloch's high altar */
- + if (Role_if(PM_INFIDEL)) {
- + /* Infidels still have an ascension run,
- + * they just carry a different McGuffin */
- + u.uevent.ascended = 0;
- + u.uachieve.amulet = 1;
- + otmp = find_quest_artifact(1 << OBJ_INVENT);
- + godvoice(A_NONE, (char *) 0);
- + if (!otmp)
- + qt_pager(QT_MOLOCH_1);
- + else {
- + qt_pager(QT_MOLOCH_2);
- + if (otmp->where == OBJ_CONTAINED) {
- + /* the Idol cannot be contained now,
- + * so we have to remove it */
- + obj_extract_self(otmp);
- + (void) hold_another_object(otmp, "Oops!",
- + (const char *) 0,
- + (const char *) 0);
- + }
- + You_feel("strange energies envelop %s.",
- + the(xname(otmp)));
- + otmp->spe = 1;
- + if (otmp->where == OBJ_INVENT)
- + u.uhave.amulet = 1;
- + }
- + return 1;
- + }
- if (u.ualign.record > -99)
- u.ualign.record = -99;
- /*[apparently shrug/snarl can be sensed without being seen]*/
- @@ -1582,8 +1658,10 @@ dosacrifice()
- if (Deaf)
- pline("Oh, no."); /* didn't hear thunderclap */
- change_luck(-3);
- - adjalign(-1);
- - u.ugangr += 3;
- + if (u.ualign.type != A_NONE) {
- + adjalign(-1);
- + u.ugangr += 3;
- + }
- value = -3;
- }
- } /* fake Amulet */
- @@ -1617,9 +1695,10 @@ dosacrifice()
- if (u.ualign.type != altaralign) {
- /* Is this a conversion ? */
- /* An unaligned altar in Gehennom will always elicit rejection. */
- + /* Infidels will also never be accepted. */
- if (ugod_is_angry() || (altaralign == A_NONE && Inhell)) {
- if (u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL]
- - && altaralign != A_NONE) {
- + && altaralign != A_NONE && !Role_if(PM_INFIDEL)) {
- You("have a strong feeling that %s is angry...",
- u_gname());
- consume_offering(otmp);
- @@ -1644,7 +1723,11 @@ dosacrifice()
- consume_offering(otmp);
- You("sense a conflict between %s and %s.", u_gname(),
- a_gname());
- - if (rn2(8 + u.ulevel) > 5) {
- + if (rn2(8 + u.ulevel) > 5
- + /* Infidels have difficulty converting altars. */
- + && !(u.ualign.type == A_NONE
- + && !(Role_if(PM_INFIDEL) && u.uhave.questart)
- + && depth(&u.uz) < depth(&valley_level) && rn2(5))) {
- struct monst *pri;
- You_feel("the power of %s increase.", u_gname());
- exercise(A_WIS, TRUE);
- @@ -1659,9 +1742,11 @@ dosacrifice()
- pline_The("altar glows %s.",
- hcolor((u.ualign.type == A_LAWFUL)
- ? NH_WHITE
- - : u.ualign.type
- - ? NH_BLACK
- - : (const char *) "gray"));
- + : u.ualign.type == A_NONE
- + ? NH_RED
- + : u.ualign.type
- + ? NH_BLACK
- + : (const char *) "gray"));
- if (rnl(u.ulevel) > 6 && u.ualign.record > 0
- && rnd(u.ualign.record) > (3 * ALIGNLIM) / 4)
- @@ -1686,8 +1771,9 @@ dosacrifice()
- consume_offering(otmp);
- /* OK, you get brownie points. */
- if (u.ugangr) {
- - u.ugangr -= ((value * (u.ualign.type == A_CHAOTIC ? 2 : 3))
- - / MAXVALUE);
- + u.ugangr -= ((value * (u.ualign.type == A_NONE ? 3
- + : u.ualign.type == A_CHAOTIC ? 4 : 6))
- + / (MAXVALUE * 2));
- if (u.ugangr < 0)
- u.ugangr = 0;
- if (u.ugangr != saved_anger) {
- @@ -1719,7 +1805,7 @@ dosacrifice()
- adjalign(value);
- You_feel("partially absolved.");
- } else if (u.ublesscnt > 0) {
- - u.ublesscnt -= ((value * (u.ualign.type == A_CHAOTIC ? 500 : 300))
- + u.ublesscnt -= ((value * (u.ualign.type <= A_CHAOTIC ? 500 : 300))
- / MAXVALUE);
- if (u.ublesscnt < 0)
- u.ublesscnt = 0;
- @@ -1799,7 +1885,7 @@ boolean praying; /* false means no messages should be given */
- p_aligntyp = on_altar() ? a_align(u.ux, u.uy) : u.ualign.type;
- p_trouble = in_trouble();
- - if (is_demon(youmonst.data) && (p_aligntyp != A_CHAOTIC)) {
- + if (is_demon(raceptr(&youmonst)) && (p_aligntyp > A_CHAOTIC)) {
- if (praying)
- pline_The("very idea of praying to a %s god is repugnant to you.",
- p_aligntyp ? "lawful" : "neutral");
- @@ -1830,13 +1916,16 @@ boolean praying; /* false means no messages should be given */
- }
- if (is_undead(youmonst.data) && !Inhell
- - && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && !rn2(10))))
- + && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && praying
- + && !rn2(10))))
- p_type = -1;
- - /* Note: when !praying, the random factor for neutrals makes the
- - return value a non-deterministic approximation for enlightenment.
- - This case should be uncommon enough to live with... */
- - return !praying ? (boolean) (p_type == 3 && !Inhell) : TRUE;
- + if (p_aligntyp == A_NONE && !on_altar()
- + && depth(&u.uz) < depth(&valley_level)
- + && !(Role_if(PM_INFIDEL) && u.uhave.questart) && praying && rn2(5))
- + p_type = -2; /* Moloch can't hear you */
- +
- + return praying || p_type == 3 && (!Inhell || u.ualign.type == A_NONE);
- }
- /* #pray commmand */
- @@ -1870,7 +1959,7 @@ dopray()
- nomovemsg = "You finish your prayer.";
- afternmv = prayer_done;
- - if (p_type == 3 && !Inhell) {
- + if (p_type == 3 && (!Inhell || u.ualign.type == A_NONE)) {
- /* if you've been true to your god you can't die while you pray */
- if (!Blind)
- You("are surrounded by a shimmering light.");
- @@ -1899,7 +1988,13 @@ prayer_done() /* M. Stephenson (1.0.3b) */
- exercise(A_CON, FALSE);
- return 1;
- }
- - if (Inhell) {
- + if (p_type == -2) {
- + pline("Unfortunately, this close to the surface %s can't hear you.",
- + align_gname(alignment));
- + /* no further effects */
- + return 0;
- + }
- + if (Inhell && u.ualign.type != A_NONE) {
- pline("Since you are in Gehennom, %s can't help you.",
- align_gname(alignment));
- /* haltingly aligned is least likely to anger */
- @@ -1977,7 +2072,7 @@ doturn()
- return (u.uconduct.gnostic == 1);
- }
- if ((u.ualign.type != A_CHAOTIC
- - && (is_demon(youmonst.data) || is_undead(youmonst.data)))
- + && (is_demon(raceptr(&youmonst)) || is_undead(youmonst.data)))
- || u.ugangr > 6) { /* "Die, mortal!" */
- pline("For some reason, %s seems to ignore you.", Gname);
- aggravate();
- @@ -2211,6 +2306,9 @@ aligntyp alignment;
- const char *gnam, *result = "god";
- switch (alignment) {
- + case A_NONE:
- + gnam = Moloch;
- + break;
- case A_LAWFUL:
- gnam = urole.lgod;
- break;
- @@ -2229,6 +2327,23 @@ aligntyp alignment;
- return result;
- }
- +/* return an alignment from a (lawful, neutral, chaotic) permutation
- + * randomly chosen at game start; only relevant to Infidels */
- +aligntyp
- +inf_align(num)
- +int num; /* 1..3 */
- +{
- + aligntyp first, other;
- + first = context.inf_aligns % 3 - 1;
- + if (num == 1)
- + return first;
- + other = (context.inf_aligns + num) % 2;
- + if (other <= first)
- + other--;
- + return other;
- +
- +}
- +
- void
- altar_wrath(x, y)
- register int x, y;
- diff --git c/src/priest.c w/src/priest.c
- index ab20a8d..92700f3 100644
- --- c/src/priest.c
- +++ w/src/priest.c
- @@ -4,6 +4,7 @@
- #include "hack.h"
- #include "mfndpos.h"
- +#include "qtext.h"
- /* these match the categorizations shown by enlightenment */
- #define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
- @@ -253,7 +254,7 @@ boolean sanctum; /* is it the seat of the high priest? */
- /* now his/her goodies... */
- if (sanctum && EPRI(priest)->shralign == A_NONE
- - && on_level(&sanctum_level, &u.uz)) {
- + && on_level(&sanctum_level, &u.uz) && !Role_if(PM_INFIDEL)) {
- (void) mongets(priest, AMULET_OF_YENDOR);
- }
- /* 2 to 4 spellbooks */
- @@ -391,7 +392,7 @@ int roomno;
- {
- struct monst *priest, *mtmp;
- struct epri *epri_p;
- - boolean shrined, sanctum, can_speak;
- + boolean shrined, sanctum, can_speak, call_guards;
- long *this_time, *other_time;
- const char *msg1, *msg2;
- char buf[BUFSZ];
- @@ -408,6 +409,7 @@ int roomno;
- sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
- && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
- can_speak = (priest->mcanmove && !priest->msleeping);
- + call_guards = FALSE;
- if (can_speak && !Deaf && moves >= epri_p->intone_time) {
- unsigned save_priest = priest->ispriest;
- @@ -425,11 +427,20 @@ int roomno;
- epri_p->enter_time = 0L;
- }
- msg1 = msg2 = 0;
- - if (sanctum && Is_sanctum(&u.uz)) {
- + if ((sanctum && Is_sanctum(&u.uz) || u.ualign.type == A_NONE)
- + && !p_coaligned(priest)) {
- + /* either a non-Infidel in the Sanctum, or an Infidel in any
- + * non-Moloch temple; either way, the priest is not happy */
- if (priest->mpeaceful) {
- /* first time inside */
- - msg1 = "Infidel, you have entered Moloch's Sanctum!";
- - msg2 = "Be gone!";
- + if (u.ualign.type == A_NONE) {
- + msg1 = "Begone, infidel!";
- + msg2 = "This place is barred for your cult!";
- + call_guards = in_town(priest->mx, priest->my);
- + } else {
- + msg1 = "Infidel, you have entered Moloch's Sanctum!";
- + msg2 = "Be gone!";
- + }
- priest->mpeaceful = 0;
- /* became angry voluntarily; no penalty for attacking him */
- set_malign(priest);
- @@ -448,6 +459,11 @@ int roomno;
- verbalize1(msg2);
- epri_p->enter_time = moves + (long) d(10, 100); /* ~505 */
- }
- + /* for Infidels, visiting the Minetown temple is a very bad idea */
- + if (call_guards) {
- + pline("%s calls for guards!", Monnam(priest));
- + (void) angry_guards(FALSE);
- + }
- if (!sanctum) {
- if (!shrined || !p_coaligned(priest)
- || u.ualign.record <= ALGN_SINNED) {
- @@ -549,7 +565,8 @@ register struct monst *priest;
- /* priests don't chat unless peaceful and in their own temple */
- if (!inhistemple(priest) || !priest->mpeaceful
- - || !priest->mcanmove || priest->msleeping) {
- + || !priest->mcanmove || priest->msleeping
- + || u.ualign.type == A_NONE && !coaligned) {
- static const char *cranky_msg[3] = {
- "Thou wouldst have words, eh? I'll give thee a word or two!",
- "Talk? Here is what I have to say!",
- @@ -576,7 +593,15 @@ register struct monst *priest;
- return;
- }
- if (!money_cnt(invent)) {
- - if (coaligned && !strayed) {
- + if (Role_if(PM_INFIDEL) && u.uachieve.amulet
- + && priest->data == &mons[PM_HIGH_PRIEST] && Is_sanctum(&u.uz)) {
- + /* give a hint about the correct high altar */
- + aligntyp saved_align = u.ualignbase[A_ORIGINAL];
- + /* a hack for displaying a different god's name in the message */
- + u.ualignbase[A_ORIGINAL] = inf_align(3);
- + qt_pager(QT_MOLOCH_3);
- + u.ualignbase[A_ORIGINAL] = saved_align;
- + } else if (coaligned && !strayed) {
- long pmoney = money_cnt(priest->minvent);
- if (pmoney > 0L) {
- /* Note: two bits is actually 25 cents. Hmm. */
- diff --git c/src/quest.c w/src/quest.c
- index df4b831..6dcc687 100644
- --- c/src/quest.c
- +++ w/src/quest.c
- @@ -219,9 +219,17 @@ finish_quest(obj)
- struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
- {
- struct obj *otmp;
- + aligntyp saved_align;
- - if (u.uhave.amulet) { /* unlikely but not impossible */
- - qt_pager(QT_HASAMULET);
- + if (u.uachieve.amulet) { /* unlikely but not impossible */
- + if (Role_if(PM_INFIDEL)) {
- + saved_align = u.ualignbase[A_ORIGINAL];
- + /* a hack for displaying a different god's name in the message */
- + u.ualignbase[A_ORIGINAL] = inf_align(2);
- + qt_pager(QT_HASAMULET);
- + u.ualignbase[A_ORIGINAL] = saved_align;
- + } else
- + qt_pager(QT_HASAMULET);
- /* leader IDs the real amulet but ignores any fakes */
- if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
- fully_identify_obj(otmp);
- @@ -255,7 +263,7 @@ chat_with_leader()
- */
- if (Qstat(got_thanks)) {
- /* Rule 1: You've gone back with/without the amulet. */
- - if (u.uhave.amulet)
- + if (u.uachieve.amulet)
- finish_quest((struct obj *) 0);
- /* Rule 2: You've gone back before going for the amulet. */
- diff --git c/src/questpgr.c w/src/questpgr.c
- index 5c04c6c..3bd8b65 100644
- --- c/src/questpgr.c
- +++ w/src/questpgr.c
- @@ -599,7 +599,7 @@ void
- com_pager(msgnum)
- int msgnum;
- {
- - struct qtmsg *qt_msg;
- + struct qtmsg *qt_msg, *alt_qt_msg;
- if (skip_pager(TRUE))
- return;
- @@ -609,6 +609,10 @@ int msgnum;
- return;
- }
- + /* optional alternate game start message; currently only Inf use it */
- + if (msgnum == 1 && (alt_qt_msg = msg_in(qt_list.chrole, QT_ALTSTART)))
- + qt_msg = alt_qt_msg;
- +
- (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
- if (qt_msg->delivery == 'p')
- deliver_by_pline(qt_msg);
- diff --git c/src/read.c w/src/read.c
- index aaa3341..f3bc78a 100644
- --- c/src/read.c
- +++ w/src/read.c
- @@ -1118,6 +1118,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
- uncurse(otmp);
- otmp->known = 1;
- setworn(otmp, W_ARM);
- + check_wings(TRUE);
- if (otmp->unpaid)
- alter_cost(otmp, 0L); /* shop bill */
- break;
- @@ -2150,7 +2151,9 @@ do_class_genocide()
- /* non-leader/nemesis/guardian role-specific monster
- */
- && (i != PM_NINJA /* nuisance */
- - || Role_if(PM_SAMURAI))) {
- + || Role_if(PM_SAMURAI))
- + && (i != PM_TEMPLAR && i != PM_CHAMPION
- + && i != PM_AGENT || Role_if(PM_INFIDEL))) {
- boolean named, uniq;
- named = type_is_pname(&mons[i]) ? TRUE : FALSE;
- diff --git c/src/role.c w/src/role.c
- index f263609..1cc0bee 100644
- --- c/src/role.c
- +++ w/src/role.c
- @@ -192,6 +192,47 @@ const struct Role roles[] = {
- A_WIS,
- SPE_CURE_SICKNESS,
- -4 },
- + { { "Infidel", 0 },
- + { { "Apostate", 0 },
- + { "Heathen", 0 },
- + { "Heretic", 0 },
- + { "Idolater", "Idolatress" },
- + { "Cultist", 0 },
- + { "Splanchomancer", 0 },
- + { "Maleficus", "Malefica" },
- + { "Demonologist", 0 },
- + { "Heresiarch", 0 } },
- + 0, 0, 0, /* uses a random role's pantheon */
- + "Inf",
- + "the Hidden Temple",
- + "the Howling Forest",
- + PM_INFIDEL,
- + NON_PM,
- + PM_HOMUNCULUS,
- + PM_PREACHER_OF_MOLOCH,
- + PM_CULTIST,
- + PM_PALADIN,
- + PM_AGENT,
- + PM_CHAMPION,
- + S_DOG,
- + S_UNICORN,
- + ART_IDOL_OF_MOLOCH, /* actually unaligned */
- + MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
- + /* Str Int Wis Dex Con Cha */
- + { 7, 7, 10, 7, 7, 7 },
- + { 20, 10, 25, 15, 20, 10 },
- + /* Init Lower Higher */
- + { 10, 0, 0, 8, 1, 0 }, /* Hit points */
- + { 4, 3, 0, 1, 0, 2 },
- + 10, /* Energy */
- + 10,
- + 3,
- + 1,
- + 2,
- + 10,
- + A_WIS,
- + SPE_FIREBALL,
- + -4 },
- { { "Knight", 0 },
- { { "Gallant", 0 },
- { "Esquire", 0 },
- @@ -725,6 +766,29 @@ const struct Race races[] = {
- { 0, 0, 0, 0 }
- };
- +/* Special race for crowned Infidels. */
- +struct Race race_demon = {
- + "demon",
- + "demonic",
- + "demonkind",
- + "Dem",
- + { 0, 0 },
- + PM_DEMON,
- + NON_PM,
- + NON_PM,
- + NON_PM,
- + MH_DEMON | ROLE_MALE | ROLE_FEMALE, /* not available at start */
- + MH_DEMON,
- + MH_DEMON,
- + MH_HUMAN | MH_ELF | MH_DWARF | MH_GNOME,
- + /* Str Int Wis Dex Con Cha */
- + { 3, 3, 3, 3, 3, 3 },
- + { STR18(100), 18, 18, 20, 20, 18 },
- + /* Init Lower Higher */
- + { 8, 0, 0, 8, 4, 0 }, /* Hit points */
- + { 4, 0, 6, 0, 6, 0 } /* Energy */
- +};
- +
- /* The player's race, created at runtime from initial
- * choices. This may be munged in role_init().
- */
- @@ -779,6 +843,16 @@ STATIC_DCL int FDECL(race_alignmentcount, (int));
- /* used by str2XXX() */
- static char NEARDATA randomstr[] = "random";
- +/* Inf are listed as chaotic above, but actually are unaligned. */
- +int
- +special_alignment(rolenum, alignnum)
- +int rolenum, alignnum;
- +{
- + if (roles[rolenum].malenum == PM_INFIDEL)
- + return 3; /* aligns[unaligned] */
- + return alignnum;
- +}
- +
- boolean
- validrole(rolenum)
- int rolenum;
- @@ -1503,12 +1577,12 @@ int buflen, rolenum, racenum, gendnum, alignnum;
- if ((racenum >= 0) && (aligncount > 1)) {
- if (donefirst)
- Strcat(buf, " ");
- - Strcat(buf, aligns[alignnum].adj);
- + Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
- donefirst = TRUE;
- } else {
- if (donefirst)
- Strcat(buf, " ");
- - Strcat(buf, aligns[alignnum].adj);
- + Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
- donefirst = TRUE;
- }
- } else {
- @@ -1800,6 +1874,7 @@ winid where;
- a = 2; /* alings[chaotic] */
- /* [c never forces gender] */
- }
- + a = special_alignment(r, a); /* special case (Infidel) */
- /* [g and a don't constrain anything sufficiently
- to narrow something done to a single choice] */
- @@ -1935,6 +2010,7 @@ boolean preselect;
- a = 1; /* aligns[neutral] */
- else if (allowmask == AM_CHAOTIC)
- a = 2; /* aligns[chaotic] */
- + a = special_alignment(r, a); /* special case (Infidel) */
- if (a >= 0)
- constrainer = "role";
- }
- @@ -2010,7 +2086,7 @@ boolean preselect;
- void
- role_init()
- {
- - int alignmnt;
- + int alignmnt, malignmnt;
- struct permonst *pm;
- /* Strip the role letter out of the player name.
- @@ -2049,7 +2125,11 @@ role_init()
- if (!validalign(flags.initrole, flags.initrace, flags.initalign))
- /* Pick a random alignment */
- flags.initalign = randalign(flags.initrole, flags.initrace);
- - alignmnt = aligns[flags.initalign].value;
- + /* Infidels are actually unaligned */
- + flags.initalign = special_alignment(flags.initrole, flags.initalign);
- + alignmnt = malignmnt = aligns[flags.initalign].value;
- + if (alignmnt != A_NONE)
- + malignmnt *= 3;
- /* Initialize urole and urace */
- urole = roles[flags.initrole];
- @@ -2061,7 +2141,7 @@ role_init()
- pm->msound = MS_LEADER;
- pm->mflags2 |= (M2_PEACEFUL);
- pm->mflags3 |= M3_CLOSE;
- - pm->maligntyp = alignmnt * 3;
- + pm->maligntyp = malignmnt;
- /* if gender is random, we choose it now instead of waiting
- until the leader monster is created */
- quest_status.ldrgend =
- @@ -2074,7 +2154,7 @@ role_init()
- if (urole.guardnum != NON_PM) {
- pm = &mons[urole.guardnum];
- pm->mflags2 |= (M2_PEACEFUL);
- - pm->maligntyp = alignmnt * 3;
- + pm->maligntyp = malignmnt;
- }
- /* Fix up the quest nemesis */
- @@ -2091,6 +2171,14 @@ role_init()
- : is_male(pm) ? 0 : (rn2(100) < 50);
- }
- + /* Enable special Inf enemies */
- + if (Role_if(PM_INFIDEL)) {
- + if (urole.enemy1num != NON_PM)
- + mons[urole.enemy1num].geno &= ~G_NOGEN;
- + if (urole.enemy2num != NON_PM)
- + mons[urole.enemy2num].geno &= ~G_NOGEN;
- + }
- +
- /* Fix up the god names */
- if (flags.pantheon == -1) { /* new game */
- flags.pantheon = flags.initrole; /* use own gods */
- diff --git c/src/shk.c w/src/shk.c
- index 6772da4..91c75f8 100644
- --- c/src/shk.c
- +++ w/src/shk.c
- @@ -4776,7 +4776,7 @@ boolean altusage; /* used as a verbalized exclamation: \"Cad! ...\" */
- {
- const char *res = 0;
- - switch (is_demon(youmonst.data) ? 3 : poly_gender()) {
- + switch (is_demon(raceptr(&youmonst)) ? 3 : poly_gender()) {
- case 0:
- res = "cad";
- break;
- diff --git c/src/sp_lev.c w/src/sp_lev.c
- index 2c5628f..4817839 100644
- --- c/src/sp_lev.c
- +++ w/src/sp_lev.c
- @@ -1624,6 +1624,14 @@ struct mkroom *croom;
- && (Race_if(PM_DWARF) || Race_if(PM_GNOME)) && rn2(3))
- pm = (struct permonst *) 0;
- + /* Make Sanctum monsters more friendly to Infidels */
- + if (u.ualign.type == A_NONE && Is_sanctum(&u.uz) && m->peaceful == 0)
- + m->peaceful = 1;
- + /* OTOH, the Astral shouldn't be easy; but the multitude of
- + * renegade minions of Moloch is still silly */
- + if (Role_if(PM_INFIDEL) && Is_astralevel(&u.uz) && amask == AM_NONE)
- + amask = Align2amask(rn1(3, -1));
- +
- if (pm) {
- int loc = pm_to_humidity(pm);
- /* If water-liking monster, first try is without DRY */
- diff --git c/src/spell.c w/src/spell.c
- index 9cbb9a4..1981718 100644
- --- c/src/spell.c
- +++ w/src/spell.c
- @@ -54,6 +54,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
- * Bar abhor magic (Conan finds it "interferes with his animal instincts")
- * Cav are ignorant to magic
- * Hea are very aware of healing magic through medical research
- + * Inf learned a lot of black magic from their cult
- * Kni are moderately aware of healing from Paladin training
- * Mon use magic to attack and defend in lieu of weapons and armor
- * Pri are very aware of healing magic through theological research
- @@ -74,6 +75,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
- * Bar fugue/berserker (SPE_HASTE_SELF)
- * Cav born to dig (SPE_DIG)
- * Hea to heal (SPE_CURE_SICKNESS)
- + * Inf to channel hellfire (SPE_FIREBALL)
- * Kni to turn back evil (SPE_TURN_UNDEAD)
- * Mon to preserve their abilities (SPE_RESTORE_ABILITY)
- * Pri to bless (SPE_REMOVE_CURSE)
- @@ -1741,6 +1743,25 @@ int spell;
- if (uarmf && is_metallic(uarmf))
- splcaster += uarmfbon;
- + /* Infidels have a special penalty for wearing blessed armor. */
- + if (Role_if(PM_INFIDEL)) {
- + static struct obj **const armor[] = { &uarm, &uarmc, &uarmh, &uarms,
- + &uarmg, &uarmf, &uarmu };
- + int penalty = 0;
- + int i;
- +
- + for (i = 0; i < SIZE(armor); i++) {
- + if (!*armor[i])
- + continue;
- + if ((*armor[i])->blessed)
- + penalty += 2;
- + else if ((*armor[i])->cursed)
- + penalty--;
- + }
- + if (penalty > 0)
- + splcaster += penalty;
- + }
- +
- if (spellid(spell) == urole.spelspec)
- splcaster += urole.spelsbon;
- diff --git c/src/teleport.c w/src/teleport.c
- index 23af60a..27a86cd 100644
- --- c/src/teleport.c
- +++ w/src/teleport.c
- @@ -842,12 +842,25 @@ level_tele()
- newlevel.dnum = destdnum;
- newlevel.dlevel = destlev;
- - if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
- + if (In_endgame(&newlevel) && !In_endgame(&u.uz)
- + && !u.uhave.amulet) {
- struct obj *amu;
- - if (!u.uhave.amulet
- - && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
- - != 0) {
- + if (!Role_if(PM_INFIDEL)) {
- + amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE);
- + } else if (amu = find_quest_artifact(1 << OBJ_INVENT)) {
- + obj_extract_self(amu); /* may be contained */
- + amu->spe = 1;
- + } else {
- + const char *idol = artiname(ART_IDOL_OF_MOLOCH);
- + amu = mksobj(FIGURINE, TRUE, FALSE);
- + artifact_exists(amu, idol, TRUE);
- + new_oname(amu, strlen(idol) + 1);
- + Strcpy(ONAME(amu), idol);
- + amu->spe = 1;
- + }
- +
- + if (amu) {
- /* ordinarily we'd use hold_another_object()
- for something like this, but we don't want
- fumbling or already full pack to interfere */
- diff --git c/src/u_init.c w/src/u_init.c
- index 77e7445..f19db59 100644
- --- c/src/u_init.c
- +++ w/src/u_init.c
- @@ -21,6 +21,7 @@ STATIC_DCL boolean FDECL(restricted_spell_discipline, (int));
- #define UNDEF_TYP 0
- #define UNDEF_SPE '\177'
- #define UNDEF_BLESS 2
- +#define CURSED 3
- /*
- * Initial inventory for the various roles.
- @@ -70,6 +71,19 @@ static struct trobj Healer[] = {
- { APPLE, 0, FOOD_CLASS, 5, 0 },
- { 0, 0, 0, 0, 0 }
- };
- +static struct trobj Infidel[] = {
- + { AMULET_OF_YENDOR, 0, AMULET_CLASS, 1, 0 },
- + { DAGGER, 1, WEAPON_CLASS, 1, 0 },
- + { LEATHER_JACKET, 1, ARMOR_CLASS, 1, CURSED },
- + { CLOAK_OF_PROTECTION, 0, ARMOR_CLASS, 1, CURSED },
- + { POT_WATER, 0, POTION_CLASS, 3, CURSED },
- + { SPE_DRAIN_LIFE, 0, SPBOOK_CLASS, 1, 0 },
- + { UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, 0 },
- + { FIRE_HORN, UNDEF_SPE, TOOL_CLASS, 1, 0 },
- + { MAGIC_MARKER, UNDEF_SPE, TOOL_CLASS, 1, 0 },
- + { 0, 0, 0, 0, 0 }
- +
- +};
- static struct trobj Knight[] = {
- { LONG_SWORD, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
- { LANCE, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
- @@ -324,6 +338,30 @@ static const struct def_skill Skill_H[] = {
- { P_BARE_HANDED_COMBAT, P_BASIC },
- { P_NONE, 0 }
- };
- +static const struct def_skill Skill_Inf[] = {
- + { P_DAGGER, P_EXPERT },
- + { P_KNIFE, P_EXPERT },
- + { P_SHORT_SWORD, P_SKILLED },
- + { P_BROAD_SWORD, P_BASIC },
- + { P_SCIMITAR, P_SKILLED },
- + { P_SABER, P_BASIC },
- + { P_CLUB, P_BASIC },
- + { P_HAMMER, P_BASIC },
- + { P_QUARTERSTAFF, P_SKILLED },
- + { P_POLEARMS, P_SKILLED },
- + { P_SPEAR, P_BASIC },
- + { P_SLING, P_BASIC },
- + { P_CROSSBOW, P_SKILLED },
- + { P_DART, P_BASIC },
- + { P_WHIP, P_SKILLED },
- + { P_ATTACK_SPELL, P_EXPERT },
- + { P_DIVINATION_SPELL, P_SKILLED },
- + { P_ENCHANTMENT_SPELL, P_BASIC },
- + { P_CLERIC_SPELL, P_EXPERT },
- + { P_BARE_HANDED_COMBAT, P_SKILLED },
- + { P_RIDING, P_SKILLED },
- + { P_NONE, 0 }
- +};
- static const struct def_skill Skill_K[] = {
- { P_DAGGER, P_BASIC },
- { P_KNIFE, P_BASIC },
- @@ -701,6 +739,12 @@ u_init()
- knows_object(POT_FULL_HEALING);
- skill_init(Skill_H);
- break;
- + case PM_INFIDEL:
- + u.umoney0 = rn1(251, 250);
- + ini_inv(Infidel);
- + knows_object(SCR_CHARGING); /* that's what the marker is for */
- + skill_init(Skill_Inf);
- + break;
- case PM_KNIGHT:
- ini_inv(Knight);
- knows_class(WEAPON_CLASS);
- @@ -927,6 +971,9 @@ int otyp;
- case PM_HEALER:
- skills = Skill_H;
- break;
- + case PM_INFIDEL:
- + skills = Skill_Inf;
- + break;
- case PM_KNIGHT:
- skills = Skill_K;
- break;
- @@ -1014,6 +1061,8 @@ register struct trobj *trop;
- || (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
- /* wizard patch -- they already have one */
- || (otyp == SPE_FORCE_BOLT && Role_if(PM_WIZARD))
- + /* same for infidels */
- + || (otyp == SPE_DRAIN_LIFE && Role_if(PM_INFIDEL))
- /* powerful spells are either useless to
- low level players or unbalancing; also
- spells in restricted skill categories */
- @@ -1086,7 +1135,7 @@ register struct trobj *trop;
- obj->cknown = obj->lknown = 1;
- obj->otrapped = 0;
- }
- - obj->cursed = 0;
- + obj->cursed = (trop->trbless == CURSED);
- if (obj->opoisoned && u.ualign.type != A_CHAOTIC)
- obj->opoisoned = 0;
- if (obj->oclass == WEAPON_CLASS || obj->oclass == TOOL_CLASS) {
- @@ -1096,10 +1145,14 @@ register struct trobj *trop;
- && obj->otyp != FLINT) {
- obj->quan = 1L;
- }
- + if (Role_if(PM_INFIDEL) && obj->oclass == ARMOR_CLASS) {
- + /* Infidels are used to playing with fire */
- + obj->oerodeproof = 1;
- + }
- if (trop->trspe != UNDEF_SPE)
- obj->spe = trop->trspe;
- if (trop->trbless != UNDEF_BLESS)
- - obj->blessed = trop->trbless;
- + obj->blessed = (trop->trbless == 1);
- }
- /* defined after setting otyp+quan + blessedness */
- obj->owt = weight(obj);
- diff --git c/src/uhitm.c w/src/uhitm.c
- index 2eedb18..d0eec28 100644
- --- c/src/uhitm.c
- +++ w/src/uhitm.c
- @@ -20,7 +20,7 @@ STATIC_DCL int FDECL(explum, (struct monst *, struct attack *));
- STATIC_DCL void FDECL(start_engulf, (struct monst *));
- STATIC_DCL void NDECL(end_engulf);
- STATIC_DCL int FDECL(gulpum, (struct monst *, struct attack *));
- -STATIC_DCL boolean FDECL(hmonas, (struct monst *));
- +STATIC_DCL boolean FDECL(hmonas, (struct monst *, int, boolean));
- STATIC_DCL void FDECL(nohandglow, (struct monst *));
- STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
- @@ -438,7 +438,7 @@ register struct monst *mtmp;
- }
- if (Upolyd)
- - (void) hmonas(mtmp);
- + (void) hmonas(mtmp, NON_PM, TRUE);
- else
- (void) hitum(mtmp, youmonst.data->mattk);
- mtmp->mstrategy &= ~STRAT_WAITMASK;
- @@ -641,6 +641,20 @@ struct attack *uattk;
- if (mhit)
- (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
- }
- +
- + /* your race may grant extra attacks */
- + if (!Upolyd && malive) {
- + int i;
- + int race = (flags.female && urace.femalenum != NON_PM)
- + ? urace.femalenum : urace.malenum;
- + struct attack *attacks = mons[race].mattk;
- + for (i = 0; i < NATTK; i++) {
- + if (attacks[i].aatyp != AT_WEAP && attacks[i].aatyp != AT_NONE) {
- + malive = hmonas(mon, race, FALSE);
- + break;
- + }
- + }
- + }
- return malive;
- }
- @@ -1327,6 +1341,15 @@ int dieroll;
- pline("%s appears confused.", Monnam(mon));
- }
- }
- + if (DEADMONSTER(mon) && attacks(AD_DREN, obj)
- + && !nonliving(mdat) && u.uen < u.uenmax) {
- + int energy = mon->m_lev + 1;
- + energy += rn2(energy);
- + pline_The("ritual knife captures the evanescent life force.");
- + u.uen += energy;
- + if (u.uen > u.uenmax)
- + u.uen = u.uenmax;
- + }
- if (unpoisonmsg)
- Your("%s %s no longer poisoned.", saved_oname,
- vtense(saved_oname, "are"));
- @@ -1643,7 +1666,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
- if (is_demon(youmonst.data) && !rn2(13) && !uwep
- && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
- - && u.umonnum != PM_BALROG) {
- + && u.umonnum != PM_BALROG && u.umonnum != PM_DEMON) {
- demonpet();
- return 0;
- }
- @@ -2346,12 +2369,14 @@ boolean wouldhavehit;
- /* attack monster as a monster; returns True if mon survives */
- STATIC_OVL boolean
- -hmonas(mon)
- +hmonas(mon, as, weapon_attacks)
- register struct monst *mon;
- +int as;
- +boolean weapon_attacks; /* skip weapon attacks if false */
- {
- struct attack *mattk, alt_attk;
- struct obj *weapon, **originalweapon;
- - boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
- + boolean altwep = FALSE, weapon_used = !weapon_attacks, odd_claw = TRUE;
- int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
- int dieroll, multi_claw = 0;
- @@ -2360,8 +2385,11 @@ register struct monst *mon;
- whether silver ring causes successful hit */
- for (i = 0; i < NATTK; i++) {
- sum[i] = 0;
- - mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
- - if (mattk->aatyp == AT_WEAP
- + if (as != NON_PM)
- + mattk = &mons[as].mattk[i];
- + else
- + mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
- + if (mattk->aatyp == AT_WEAP && weapon_attacks
- || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
- ++multi_claw;
- }
- @@ -2369,11 +2397,16 @@ register struct monst *mon;
- for (i = 0; i < NATTK; i++) {
- /* sum[i] = 0; -- now done above */
- - mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
- + if (as != NON_PM)
- + mattk = &mons[as].mattk[i];
- + else
- + mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
- weapon = 0;
- switch (mattk->aatyp) {
- case AT_WEAP:
- /* if (!uwep) goto weaponless; */
- + if (!weapon_attacks)
- + continue;
- use_weapon:
- odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
- /* if we've already hit with a two-handed weapon, we don't
- diff --git c/src/weapon.c w/src/weapon.c
- index 1027409..573c050 100644
- --- c/src/weapon.c
- +++ w/src/weapon.c
- @@ -1610,6 +1610,8 @@ const struct def_skill *class_skill;
- /* set skills for magic */
- if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
- P_SKILL(P_HEALING_SPELL) = P_BASIC;
- + } else if (Role_if(PM_INFIDEL)) {
- + P_SKILL(P_ATTACK_SPELL) = P_BASIC;
- } else if (Role_if(PM_PRIEST)) {
- P_SKILL(P_CLERIC_SPELL) = P_BASIC;
- } else if (Role_if(PM_WIZARD)) {
- diff --git c/src/wield.c w/src/wield.c
- index 18c276a..07b7ca3 100644
- --- c/src/wield.c
- +++ w/src/wield.c
- @@ -64,6 +64,8 @@ STATIC_DCL int FDECL(ready_weapon, (struct obj *));
- /* used by welded(), and also while wielding */
- #define will_weld(optr) \
- ((optr)->cursed && (erodeable_wep(optr) || (optr)->otyp == TIN_OPENER))
- +/* Infidels are immune to curses */
- +#define will_weld_to_you(optr) (will_weld(optr) && !Role_if(PM_INFIDEL))
- /*** Functions that place a given item in a slot ***/
- /* Proper usage includes:
- @@ -160,7 +162,7 @@ struct obj *wep;
- } else {
- /* Weapon WILL be wielded after this point */
- res++;
- - if (will_weld(wep)) {
- + if (will_weld_to_you(wep)) {
- const char *tmp = xname(wep), *thestr = "The ";
- if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
- @@ -575,7 +577,7 @@ const char *verb; /* "rub",&c */
- } else {
- struct obj *oldwep = uwep;
- - if (will_weld(obj)) {
- + if (will_weld_to_you(obj)) {
- /* hope none of ready_weapon()'s early returns apply here... */
- (void) ready_weapon(obj);
- } else {
- @@ -858,7 +860,7 @@ int
- welded(obj)
- register struct obj *obj;
- {
- - if (obj && obj == uwep && will_weld(obj)) {
- + if (obj && obj == uwep && will_weld_to_you(obj)) {
- set_bknown(obj, 1);
- return 1;
- }
- diff --git c/src/wizard.c w/src/wizard.c
- index b1dae1e..fd7281e 100644
- --- c/src/wizard.c
- +++ w/src/wizard.c
- @@ -66,7 +66,9 @@ amulet()
- return;
- #endif
- if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR)
- - || ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR))
- + || ((amu = uwep) != 0 && (amu->otyp == AMULET_OF_YENDOR
- + || amu->oartifact == ART_IDOL_OF_MOLOCH
- + && amu->spe)))
- && !rn2(15)) {
- for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
- if (ttmp->ttyp == MAGIC_PORTAL) {
- @@ -106,7 +108,8 @@ register struct monst *mtmp;
- register struct obj *otmp;
- for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
- - if (otmp->otyp == AMULET_OF_YENDOR)
- + if (otmp->otyp == AMULET_OF_YENDOR
- + || otmp->oartifact == ART_IDOL_OF_MOLOCH && otmp->spe)
- return 1;
- return 0;
- }
- diff --git c/src/worn.c w/src/worn.c
- index 1a966b7..db2b27d 100644
- --- c/src/worn.c
- +++ w/src/worn.c
- @@ -578,6 +578,10 @@ boolean racialexception;
- continue;
- if (racialexception && (racial_exception(mon, obj) < 1))
- continue;
- + /* monsters won't sacrifice flight for AC */
- + if (big_wings(mon->data) && !Is_dragon_scales(obj)
- + && obj->otyp != LEATHER_JACKET)
- + continue;
- break;
- }
- if (obj->owornmask)
- diff --git c/src/zap.c w/src/zap.c
- index 1c7a5de..2784f34 100644
- --- c/src/zap.c
- +++ w/src/zap.c
- @@ -1182,6 +1182,7 @@ struct obj *obj;
- int ochance, achance; /* percent chance for ordinary objects, artifacts */
- {
- if (obj->otyp == AMULET_OF_YENDOR
- + || Role_if(PM_INFIDEL) && is_quest_artifact(obj)
- || obj->otyp == SPE_BOOK_OF_THE_DEAD
- || obj->otyp == CANDELABRUM_OF_INVOCATION
- || obj->otyp == BELL_OF_OPENING
- @@ -2446,7 +2447,7 @@ boolean ordinary;
- case WAN_DEATH:
- case SPE_FINGER_OF_DEATH:
- - if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
- + if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
- pline((obj->otyp == WAN_DEATH)
- ? "The wand shoots an apparently harmless beam at you."
- : "You seem no deader than before.");
- @@ -3838,7 +3839,7 @@ xchar sx, sy;
- (void) destroy_arm(uarmc);
- if (uarmu)
- (void) destroy_arm(uarmu);
- - } else if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
- + } else if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
- shieldeff(sx, sy);
- You("seem unaffected.");
- break;
- diff --git c/sys/amiga/Makefile.agc w/sys/amiga/Makefile.agc
- index 47040b5..b13632e 100644
- --- c/sys/amiga/Makefile.agc
- +++ w/sys/amiga/Makefile.agc
- @@ -228,6 +228,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
- $(SLIB)Hea-strt.lev
- HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
- +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
- + $(SLIB)Inf-strt.lev
- +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
- +
- KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
- $(SLIB)Kni-strt.lev
- KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
- @@ -264,7 +268,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
- $(SLIB)Wiz-strt.lev
- WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
- -XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
- +XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
- $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
- $(VDFILES) $(WDFILES)
- @@ -843,6 +847,10 @@ $(HDFILES1): $(SLIB)Hea-goal.lev
- $(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp
- +$(IDFILES1): $(SLIB)Inf-goal.lev
- +
- +$(SLIB)Inf-goal.lev: $(DAT)Infidel.des $(SBIN)lev_comp
- +
- $(KDFILES1): $(SLIB)Kni-goal.lev
- $(SLIB)Kni-goal.lev: $(DAT)Knight.des $(SBIN)lev_comp
- diff --git c/sys/amiga/Makefile.ami w/sys/amiga/Makefile.ami
- index 14b1298..6fefee5 100644
- --- c/sys/amiga/Makefile.ami
- +++ w/sys/amiga/Makefile.ami
- @@ -435,6 +435,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
- $(SLIB)Hea-strt.lev
- HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
- +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
- + $(SLIB)Inf-strt.lev
- +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
- +
- KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
- $(SLIB)Kni-strt.lev
- KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
- @@ -471,7 +475,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
- $(SLIB)Wiz-strt.lev
- WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
- -XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
- +XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
- $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
- $(VDFILES) $(WDFILES)
- @@ -1148,6 +1152,12 @@ $(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp
- #SFD_INSTEAD $(SBIN)lev_comp $(DAT)Healer.des
- #none
- +$(IDFILES1): $(SLIB)Inf-goal.lev
- +
- +$(SLIB)Inf-goal.lev: $(DAT)Infidel.des $(SBIN)lev_comp
- +#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Infidel.des
- +#none
- +
- $(KDFILES1): $(SLIB)Kni-goal.lev
- $(SLIB)Kni-goal.lev: $(DAT)Knight.des $(SBIN)lev_comp
- diff --git c/sys/msdos/Makefile.BC w/sys/msdos/Makefile.BC
- index ce0756a..5476f58 100644
- --- c/sys/msdos/Makefile.BC
- +++ w/sys/msdos/Makefile.BC
- @@ -718,7 +718,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
- $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
- $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
- $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
- - $(DAT)\Wizard.des $(DAT)\yendor.des
- + $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
- #
- # Utility Objects.
- @@ -976,6 +976,7 @@ $(DAT)\sp_lev.tag: $(U)utility.tag $(SPLEVDES)
- $(U)lev_comp barb.des
- $(U)lev_comp caveman.des
- $(U)lev_comp healer.des
- + $(U)lev_comp infidel.des
- $(U)lev_comp knight.des
- $(U)lev_comp monk.des
- $(U)lev_comp priest.des
- diff --git c/sys/msdos/Makefile.GCC w/sys/msdos/Makefile.GCC
- index 4693bda..579f11a 100644
- --- c/sys/msdos/Makefile.GCC
- +++ w/sys/msdos/Makefile.GCC
- @@ -1016,7 +1016,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
- $(DAT)/caveman.des $(DAT)/healer.des $(DAT)/knight.des \
- $(DAT)/monk.des $(DAT)/priest.des $(DAT)/ranger.des \
- $(DAT)/rogue.des $(DAT)/samurai.des $(DAT)/tourist.des \
- - $(DAT)/valkyrie.des $(DAT)/wizard.des
- + $(DAT)/valkyrie.des $(DAT)/wizard.des $(DAT)/infidel.des
- @$(subst /,\,cd $(DAT))
- @$(subst /,\,$(U)lev_comp bigroom.des)
- @$(subst /,\,$(U)lev_comp castle.des)
- @@ -1033,6 +1033,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
- @$(subst /,\,$(U)lev_comp barb.des)
- @$(subst /,\,$(U)lev_comp caveman.des)
- @$(subst /,\,$(U)lev_comp healer.des)
- + @$(subst /,\,$(U)lev_comp infidel.des)
- @$(subst /,\,$(U)lev_comp knight.des)
- @$(subst /,\,$(U)lev_comp monk.des)
- @$(subst /,\,$(U)lev_comp priest.des)
- diff --git c/sys/msdos/Makefile.MSC w/sys/msdos/Makefile.MSC
- index b7d827a..b605dcc 100644
- --- c/sys/msdos/Makefile.MSC
- +++ w/sys/msdos/Makefile.MSC
- @@ -148,7 +148,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
- $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
- $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
- $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
- - $(DAT)\Wizard.des $(DAT)\yendor.des
- + $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
- VGAOBJ = vidvga.o
- @@ -428,6 +428,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(SPLEVDES)
- $(U)lev_comp barb.des
- $(U)lev_comp caveman.des
- $(U)lev_comp healer.des
- + $(U)lev_comp infidel.des
- $(U)lev_comp knight.des
- $(U)lev_comp monk.des
- $(U)lev_comp priest.des
- @@ -973,6 +974,11 @@ nhdat: $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(DAT)\options \
- echo HEA-GOAL.LEV >>dlb.lst
- echo HEA-LOCA.LEV >>dlb.lst
- echo HEA-STRT.LEV >>dlb.lst
- + echo INF-FILA.LEV >>dlb.lst
- + echo INF-FILB.LEV >>dlb.lst
- + echo INF-GOAL.LEV >>dlb.lst
- + echo INF-LOCA.LEV >>dlb.lst
- + echo INF-STRT.LEV >>dlb.lst
- echo JUIBLEX.LEV >>dlb.lst
- echo KNI-FILA.LEV >>dlb.lst
- echo KNI-FILB.LEV >>dlb.lst
- diff --git c/sys/os2/Makefile.os2 w/sys/os2/Makefile.os2
- index 4afcf0f..9ddaad5 100644
- --- c/sys/os2/Makefile.os2
- +++ w/sys/os2/Makefile.os2
- @@ -1280,6 +1280,7 @@ AFILES = $(GAMEDIR)\Arc-goal.lev
- BFILES = $(GAMEDIR)\Bar-goal.lev
- CFILES = $(GAMEDIR)\Cav-goal.lev
- HFILES = $(GAMEDIR)\Hea-goal.lev
- +IFILES = $(GAMEDIR)\Inf-goal.lev
- KFILES = $(GAMEDIR)\Kni-goal.lev
- MFILES = $(GAMEDIR)\Mon-goal.lev
- PFILES = $(GAMEDIR)\Pri-goal.lev
- @@ -1290,7 +1291,7 @@ TFILES = $(GAMEDIR)\Tou-goal.lev
- VFILES = $(GAMEDIR)\Val-goal.lev
- WFILES = $(GAMEDIR)\Wiz-goal.lev
- -XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(KFILES) $(MFILES) \
- +XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(IFILES) $(KFILES) $(MFILES) \
- $(PFILES) $(RANFILES) $(RFILES) $(SFILES) $(TFILES) $(VFILES) $(WFILES)
- spec_lev : $(GAMEDIR)\astral.lev $(GAMEDIR)\bigrm-1.lev $(GAMEDIR)\castle.lev \
- @@ -1389,6 +1390,8 @@ $(CFILES) : $(DAT)\Caveman.des $(TEMP)\lev_comp.exe
- $(MAKEB) QQ=Cav QF=Caveman do_quest
- $(HFILES) : $(DAT)\Healer.des $(TEMP)\lev_comp.exe
- $(MAKEB) QQ=Hea QF=Healer do_quest
- +$(IFILES) : $(DAT)\Infidel.des $(TEMP)\lev_comp.exe
- + $(MAKEB) QQ=Inf QF=Infidel do_quest
- $(KFILES) : $(DAT)\Knight.des $(TEMP)\lev_comp.exe
- $(MAKEB) QQ=Kni QF=Knight do_quest
- $(MFILES) : $(DAT)\Monk.des $(TEMP)\lev_comp.exe
- diff --git c/sys/unix/Makefile.dat w/sys/unix/Makefile.dat
- index 00f6043..c6bb10d 100644
- --- c/sys/unix/Makefile.dat
- +++ w/sys/unix/Makefile.dat
- @@ -145,11 +145,12 @@ spec_levs: ../util/lev_comp \
- quest_levs: ../util/lev_comp \
- Arch.des Barb.des Caveman.des Healer.des Knight.des Monk.des \
- Priest.des Ranger.des Rogue.des Samurai.des Tourist.des Valkyrie.des \
- - Wizard.des
- + Wizard.des Infidel.des
- ../util/lev_comp Arch.des
- ../util/lev_comp Barb.des
- ../util/lev_comp Caveman.des
- ../util/lev_comp Healer.des
- + ../util/lev_comp Infidel.des
- ../util/lev_comp Knight.des
- ../util/lev_comp Monk.des
- ../util/lev_comp Priest.des
- diff --git c/sys/unix/NetHack.xcodeproj/project.pbxproj w/sys/unix/NetHack.xcodeproj/project.pbxproj
- index fdee884..d0db85a 100644
- --- c/sys/unix/NetHack.xcodeproj/project.pbxproj
- +++ w/sys/unix/NetHack.xcodeproj/project.pbxproj
- @@ -1310,6 +1310,7 @@
- "$(NH_DAT_DIR)/Barb.des",
- "$(NH_DAT_DIR)/Caveman.des",
- "$(NH_DAT_DIR)/Healer.des",
- + "$(NH_DAT_DIR)/Infidel.des",
- "$(NH_DAT_DIR)/Knight.des",
- "$(NH_DAT_DIR)/Monk.des",
- "$(NH_DAT_DIR)/Priest.des",
- @@ -1328,7 +1329,7 @@
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- - 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";
- + 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";
- };
- 317E7C4E21A3697300F6E4E5 /* Build options and headers */ = {
- isa = PBXShellScriptBuildPhase;
- @@ -1472,6 +1473,11 @@
- "$(NH_DAT_DIR)/Hea-goal.lev",
- "$(NH_DAT_DIR)/Hea-loca.lev",
- "$(NH_DAT_DIR)/Hea-strt.lev",
- + "$(NH_DAT_DIR)/Inf-fila.lev",
- + "$(NH_DAT_DIR)/Inf-filb.lev",
- + "$(NH_DAT_DIR)/Inf-goal.lev",
- + "$(NH_DAT_DIR)/Inf-loca.lev",
- + "$(NH_DAT_DIR)/Inf-strt.lev",
- "$(NH_DAT_DIR)/Kni-fila.lev",
- "$(NH_DAT_DIR)/Kni-filb.lev",
- "$(NH_DAT_DIR)/Kni-goal.lev",
- diff --git c/sys/vms/Makefile.dat w/sys/vms/Makefile.dat
- index e74eb95..dea0fb8 100644
- --- c/sys/vms/Makefile.dat
- +++ w/sys/vms/Makefile.dat
- @@ -31,7 +31,7 @@ VARDAT = data.;,rumors.;,quest.dat;,oracles.;,options.;,\
- DUNGEON = dungeon.;
- X11TILES= x11tiles.;
- # note: the level lists need to be space separated for use as-is by $(LEVCOMP)
- -QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Knight.des \
- +QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Infidel.des Knight.des \
- Monk.des Priest.des Ranger.des Rogue.des Samurai.des Tourist.des \
- Valkyrie.des Wizard.des
- SPECLEVS = bigroom.des castle.des endgame.des gehennom.des knox.des \
- diff --git c/sys/vms/install.com w/sys/vms/install.com
- index 09f6f83..5172e41 100755
- --- c/sys/vms/install.com
- +++ w/sys/vms/install.com
- @@ -45,7 +45,7 @@ $ spec_input = "bigroom.des castle.des endgame.des " -
- + "gehennom.des knox.des medusa.des mines.des " -
- + "oracle.des sokoban.des tower.des yendor.des"
- $ qstl_files = "%%%-GOAL.LEV,%%%-FIL%.LEV,%%%-LOCA.LEV,%%%-STRT.LEV"
- -$ qstl_input = "Arch.des Barb.des Caveman.des Healer.des " -
- +$ qstl_input = "Arch.des Barb.des Caveman.des Healer.des Infidel.des " -
- + "Knight.des Monk.des Priest.des Ranger.des Rogue.des " -
- + "Samurai.des Tourist.des Wizard.des Valkyrie.des"
- $ dngn_files = "DUNGEON."
- diff --git c/sys/wince/bootstrp.mak w/sys/wince/bootstrp.mak
- index 5d92dc7..dcd3a46 100644
- --- c/sys/wince/bootstrp.mak
- +++ w/sys/wince/bootstrp.mak
- @@ -244,7 +244,8 @@ $(O)sp_lev.tag: $(DAT)\bigroom.des $(DAT)\castle.des \
- $(DAT)\caveman.des $(DAT)\healer.des $(DAT)\knight.des \
- $(DAT)\monk.des $(DAT)\priest.des $(DAT)\ranger.des \
- $(DAT)\rogue.des $(DAT)\samurai.des $(DAT)\sokoban.des \
- - $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
- + $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
- + $(DAT)\infidel.des
- cd $(DAT)
- $(U)lev_comp bigroom.des
- $(U)lev_comp castle.des
- @@ -261,6 +262,7 @@ $(O)sp_lev.tag: $(DAT)\bigroom.des $(DAT)\castle.des \
- $(U)lev_comp barb.des
- $(U)lev_comp caveman.des
- $(U)lev_comp healer.des
- + $(U)lev_comp infidel.des
- $(U)lev_comp knight.des
- $(U)lev_comp monk.des
- $(U)lev_comp priest.des
- diff --git c/sys/winnt/Makefile.msc w/sys/winnt/Makefile.msc
- index 6421a70..c9438c6 100644
- --- c/sys/winnt/Makefile.msc
- +++ w/sys/winnt/Makefile.msc
- @@ -711,7 +711,8 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des $(DAT)\castle.des \
- $(DAT)\caveman.des $(DAT)\healer.des $(DAT)\knight.des \
- $(DAT)\monk.des $(DAT)\priest.des $(DAT)\ranger.des \
- $(DAT)\rogue.des $(DAT)\samurai.des $(DAT)\sokoban.des \
- - $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
- + $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
- + $(DAT)\infidel.des
- cd $(DAT)
- $(U)levcomp bigroom.des
- $(U)levcomp castle.des
- @@ -728,6 +729,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des $(DAT)\castle.des \
- $(U)levcomp barb.des
- $(U)levcomp caveman.des
- $(U)levcomp healer.des
- + $(U)levcomp infidel.des
- $(U)levcomp knight.des
- $(U)levcomp monk.des
- $(U)levcomp priest.des
- diff --git c/util/lev_main.c w/util/lev_main.c
- index 8bcfc83..15a487f 100644
- --- c/util/lev_main.c
- +++ w/util/lev_main.c
- @@ -250,7 +250,8 @@ char **argv;
- ":dat:Wizard.des", ":dat:bigroom.des", ":dat:castle.des",
- ":dat:endgame.des", ":dat:gehennom.des", ":dat:knox.des",
- ":dat:medusa.des", ":dat:mines.des", ":dat:oracle.des",
- - ":dat:sokoban.des", ":dat:tower.des", ":dat:yendor.des"
- + ":dat:sokoban.des", ":dat:tower.des", ":dat:yendor.des",
- + ":dat:Infidel.des"
- };
- argc = SIZE(mac_argv);
- diff --git c/win/tty/wintty.c w/win/tty/wintty.c
- index d7ffec6..d5c18bb 100644
- --- c/win/tty/wintty.c
- +++ w/win/tty/wintty.c
- @@ -929,6 +929,7 @@ tty_player_selection()
- */
- getconfirmation = (picksomething && pick4u != 'a' && !flags.randomall);
- while (getconfirmation) {
- + int real_algn = special_alignment(ROLE, ALGN);
- tty_clear_nhwindow(BASE_WINDOW);
- role_selection_prolog(ROLE_NONE, BASE_WINDOW);
- win = create_nhwindow(NHW_MENU);
- @@ -941,7 +942,7 @@ tty_player_selection()
- Sprintf(plbuf, " %s", genders[GEND].adj);
- else
- *plbuf = '\0'; /* omit redundant gender */
- - Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[ALGN].adj, plbuf,
- + Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[real_algn].adj, plbuf,
- races[RACE].adj,
- (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f
- : roles[ROLE].name.m);
- diff --git c/win/win32/vs2017/files.props w/win/win32/vs2017/files.props
- index 483ec1e..5a12ab8 100644
- --- c/win/win32/vs2017/files.props
- +++ w/win/win32/vs2017/files.props
- @@ -35,6 +35,7 @@
- <Desfiles Include = "endgame.des"/>
- <Desfiles Include = "gehennom.des"/>
- <Desfiles Include = "healer.des"/>
- + <Desfiles Include = "infidel.des"/>
- <Desfiles Include = "knight.des"/>
- <Desfiles Include = "knox.des"/>
- <Desfiles Include = "medusa.des"/>
- @@ -128,6 +129,11 @@
- <Levfiles Include = "hea-goal.lev"/>
- <Levfiles Include = "hea-loca.lev"/>
- <Levfiles Include = "hea-strt.lev"/>
- + <Levfiles Include = "inf-fila.lev"/>
- + <Levfiles Include = "inf-filb.lev"/>
- + <Levfiles Include = "inf-goal.lev"/>
- + <Levfiles Include = "inf-loca.lev"/>
- + <Levfiles Include = "inf-strt.lev"/>
- <Levfiles Include = "kni-fila.lev"/>
- <Levfiles Include = "kni-filb.lev"/>
- <Levfiles Include = "kni-goal.lev"/>
Add Comment
Please, Sign In to add comment