endgame: high altars, offering the Amulet to Moloch (trunk only)

Several small related changes that ended up being not quite so small:

     Allow the Amulet of Yendor to be offered on the altar in the temple
of Moloch's Sanctum level; doing so is fatal.  Fake ones can be offered
too, but that doesn't do anything special (they act the same as they do in
the temples on the Astral level).  Unlike in the endgame, the Amulet and
its fakes aren't listed as likely candidate for #offer's pick-an-object
prompt; like the endgame, corpses must be carried rather than being on
the altar in order to be sacrificed.

     Prevent non-chaotics from destroying the chaotic high altar on the
Astral level via same-race sacrifice.  From a bug report.  (Chaotics converting non-chaotic high altars
via same method was already handled.  I think the behavior for ordinary
altars if wrong here; why should a chaotic altar be destroyed this way?)

     Prevent demon princes and demon lords from being summoned in the
endgame.  Lesser demons answer instead.  Mostly prevents Yeenoghu from
being summoned by a chaotic who performs same-race sacrified on the
chaotic high altar, but might affect the Wizard and arch-liches too.

     Identify (via ':', ';', '/') altars in temples on the Astral and
Sanctum levels as "high altars" rather than just as "altars".  '/' and ';'
commands now work on those when you're adjacent, like they do when used on
adjacent high priests; from farther away, the altars' alignment is still
suppressed.
This commit is contained in:
nethack.rankin
2006-12-05 03:09:13 +00:00
parent cbd61ce625
commit 1bb8545563
5 changed files with 54 additions and 21 deletions

View File

@@ -176,6 +176,8 @@ worn item transformed by polymorph remains worn if feasible
can't dip or apply grease to a worn item that's covered by another worn item
hero poly'd into stone golem and wielding cockatrice corpse casts stone-to-
flesh at self to become flesh golem will revert to stone if no gloves
demon lords/princes can't be summoned to the elemental or Astral planes
same-race sacrifice can't damage high altars
Platform- and/or Interface-Specific Fixes
@@ -262,6 +264,7 @@ multiple squeaks for squeaky boards
include time, user ID, and play mode in paniclog entries
add oracle and rumor regarding priestly donations
anti-magic traps have alternate effect on targets who have magic resistance
the Amulet can be offered to Moloch
Platform- and/or Interface-Specific New Features

View File

@@ -925,6 +925,8 @@ register const char *let,*word;
|| (!strncmp(word, "rub on the stone", 16) &&
*let == GEM_CLASS &&
otmp->dknown && objects[otyp].oc_name_known)
|| (!strcmp(word, "sacrifice") && Is_sanctum(&u.uz) &&
(otyp == AMULET_OF_YENDOR || otyp == FAKE_AMULET_OF_YENDOR))
) {
foo--;
allowall = TRUE;
@@ -2228,7 +2230,11 @@ char *buf;
cmap = S_sink; /* "sink" */
#endif
else if (IS_ALTAR(ltyp)) {
Sprintf(altbuf, "altar to %s (%s)", a_gname(),
Sprintf(altbuf, "%saltar to %s (%s)",
((lev->altarmask & AM_SHRINE) &&
(Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) ?
"high " : "",
a_gname(),
align_str(Amask2align(lev->altarmask & ~AM_SHRINE)));
dfeature = altbuf;
} else if ((x == xupstair && y == yupstair) ||

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)minion.c 3.5 2006/09/06 */
/* SCCS Id: @(#)minion.c 3.5 2006/12/04 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -299,7 +299,7 @@ aligntyp atyp;
{
int tryct, pm;
for (tryct = 0; tryct < 20; tryct++) {
for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
if (!(mvitals[pm].mvflags & G_GONE) &&
(atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
@@ -314,7 +314,7 @@ aligntyp atyp;
{
int tryct, pm;
for (tryct = 0; tryct < 20; tryct++) {
for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
if (!(mvitals[pm].mvflags & G_GONE) &&
(atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)pager.c 3.5 2006/07/08 */
/* SCCS Id: @(#)pager.c 3.5 2006/12/02 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -266,10 +266,13 @@ lookat(x, y, buf, monbuf)
Strcpy(buf,"dark part of a room");
} else switch(glyph_to_cmap(glyph)) {
case S_altar:
if(!In_endgame(&u.uz))
Sprintf(buf, "%s altar",
align_str(Amask2align(levl[x][y].altarmask & ~AM_SHRINE)));
else Sprintf(buf, "aligned altar");
Sprintf(buf, "%s %saltar",
/* like endgame high priests, endgame high altars
are only recognizable when immediately adjacent */
(Is_astralevel(&u.uz) && distu(x, y) > 2) ? "aligned" :
align_str(Amask2align(levl[x][y].altarmask & ~AM_SHRINE)),
((levl[x][y].altarmask & AM_SHRINE) &&
(Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) ? "high " : "");
break;
case S_ndoor:
if (is_drawbridge_wall(x, y) >= 0)

View File

@@ -1156,17 +1156,21 @@ register struct obj *otmp;
int
dosacrifice()
{
static NEARDATA const char cloud_of_smoke[] =
"A cloud of %s smoke surrounds you...";
register struct obj *otmp;
int value = 0;
int pm;
int value = 0, pm;
boolean highaltar;
aligntyp altaralign = a_align(u.ux,u.uy);
if (!on_altar() || u.uswallow) {
You("are not standing on an altar.");
return 0;
}
highaltar = ((Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) &&
(levl[u.ux][u.uy].altarmask & AM_SHRINE));
if (In_endgame(&u.uz)) {
if (highaltar) {
if (!(otmp = getobj(sacrifice_types, "sacrifice"))) return 0;
} else {
if (!(otmp = floorfood("sacrifice", 1))) return 0;
@@ -1210,11 +1214,13 @@ dosacrifice()
exercise(A_WIS, FALSE);
}
if (altaralign != A_CHAOTIC && altaralign != A_NONE) {
if (highaltar &&
(altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)) {
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);
if(!Is_astralevel(&u.uz))
levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
angry_priest();
} else {
struct monst *dmon;
@@ -1306,7 +1312,7 @@ dosacrifice()
} /* corpse */
if (otmp->otyp == AMULET_OF_YENDOR) {
if (!Is_astralevel(&u.uz)) {
if (!highaltar) {
if (Hallucination)
You_feel("homesick.");
else
@@ -1319,7 +1325,23 @@ dosacrifice()
if(carried(otmp)) useup(otmp); /* well, it's gone now */
else useupf(otmp, 1L);
You("offer the Amulet of Yendor to %s...", a_gname());
if (u.ualign.type != altaralign) {
if (altaralign == A_NONE) {
/* Moloch's high altar */
if (u.ualign.record > -99) u.ualign.record = -99;
/*[apparently shrug/snarl can be sensed without being seen]*/
pline("%s shrugs and retains dominion over %s,",
Moloch, u_gname());
pline("then mercilessly snuffs out your life.");
Sprintf(killer.name, "%s indifference", s_suffix(Moloch));
killer.format = KILLED_BY;
done(DIED);
/* life-saved (or declined to die in wizard/explore mode) */
pline("%s snarls and tries again...", Moloch);
fry_by_god(A_NONE); /* wrath of Moloch */
/* declined to die in wizard or explore mode */
pline(cloud_of_smoke, hcolor(NH_BLACK));
done(ESCAPED);
} else if (u.ualign.type != altaralign) {
/* And the opposing team picks you up and
carries you off on their shoulders */
adjalign(-99);
@@ -1327,8 +1349,7 @@ dosacrifice()
a_gname(), u_gname());
pline("%s is enraged...", u_gname());
pline("Fortunately, %s permits you to live...", a_gname());
pline("A cloud of %s smoke surrounds you...",
hcolor((const char *)"orange"));
pline(cloud_of_smoke, hcolor("orange"));
done(ESCAPED);
} else { /* super big win */
adjalign(10);
@@ -1366,8 +1387,8 @@ verbalize("In return for thy service, I grant thee the gift of Immortality!");
return (1);
}
if (altaralign != u.ualign.type &&
(Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
if (altaralign != u.ualign.type && highaltar) {
desecrate_high_altar:
/*
* REAL BAD NEWS!!! High altars cannot be converted. Even an attempt
* gets the god who owns it truely pissed off.