sacrificing tune-up (trunk only)

There was code to give feedback if you attempted to offer the Amulet
on a regular altar instead of the final high altar, but that code was
unreachable; getobj() yielded "that's a silly thing" whenever you picked
an amulet while not on the Astral (or recently changed, Sanctum) level.
This allows you to try to offer the real or fake Amulet of Yendor on any
altar, but they'll only be listed as likely candidates when on the Astral
level.  Conversely, it no longer lists carried corpses as likely candidates
at the Astral high altars; they're still acceptable but not what the hero
is supposed to be fiddling with there.  Also, allow corpses on the floor
to be offered on high altars, fixing a complaint we've gotten a few times
over the years.  (Unfortunately there's no way to suppress them as likely
candidates on the high altars while still allowing them to be sacrified.)
This commit is contained in:
nethack.rankin
2006-12-08 04:44:25 +00:00
parent 79ced450e7
commit 1505e3e7d7
4 changed files with 28 additions and 17 deletions

View File

@@ -178,6 +178,8 @@ 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
allow corpses on floor to be offered at high altars
allow hero to attempt to offer the Amulet at ordinary altars
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)eat.c 3.5 2006/10/06 */
/* SCCS Id: @(#)eat.c 3.5 2006/12/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -74,6 +74,7 @@ char msgbuf[BUFSZ];
#define nonrotting_food(otyp) ((otyp) == LEMBAS_WAFER || (otyp) == CRAM_RATION)
STATIC_OVL NEARDATA const char comestibles[] = { FOOD_CLASS, 0 };
STATIC_OVL NEARDATA const char offerfodder[] = { FOOD_CLASS, AMULET_CLASS, 0 };
/* Gold must come first for getobj(). */
STATIC_OVL NEARDATA const char allobj[] = {
@@ -2760,7 +2761,8 @@ floorfood(verb,corpsecheck) /* get food from floor or pack */
register struct obj *otmp;
char qbuf[QBUFSZ];
char c;
boolean feeding = (!strcmp(verb, "eat"));
boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */
offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */
/* if we can't touch floor objects then use invent food only */
if (!can_reach_floor(TRUE) ||
@@ -2834,9 +2836,9 @@ floorfood(verb,corpsecheck) /* get food from floor or pack */
/* We cannot use ALL_CLASSES since that causes getobj() to skip its
* "ugly checks" and we need to check for inedible items.
*/
otmp = getobj(feeding ? (const char *)allobj :
(const char *)comestibles, verb);
if (corpsecheck && otmp)
otmp = getobj(feeding ? allobj : offering ? offerfodder : comestibles,
verb);
if (corpsecheck && otmp && !(offering && otmp->oclass == AMULET_CLASS))
if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
You_cant("%s that!", verb);
return (struct obj *)0;

View File

@@ -925,9 +925,12 @@ 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))
/* suppress corpses on astral, amulets elsewhere */
|| (!strcmp(word, "sacrifice") &&
/* (!astral && amulet) || (astral && !amulet) */
(!Is_astralevel(&u.uz) ^ otmp->oclass != AMULET_CLASS))
) {
/* acceptable but not listed as likely candidate */
foo--;
allowall = TRUE;
*ap++ = otmp->invlet;

View File

@@ -1126,8 +1126,6 @@ gods_upset(g_align)
angrygods(g_align);
}
static NEARDATA const char sacrifice_types[] = { FOOD_CLASS, AMULET_CLASS, 0 };
STATIC_OVL void
consume_offering(otmp)
register struct obj *otmp;
@@ -1170,11 +1168,8 @@ dosacrifice()
highaltar = ((Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) &&
(levl[u.ux][u.uy].altarmask & AM_SHRINE));
if (highaltar) {
if (!(otmp = getobj(sacrifice_types, "sacrifice"))) return 0;
} else {
if (!(otmp = floorfood("sacrifice", 1))) return 0;
}
otmp = floorfood("sacrifice", 1);
if (!otmp) return 0;
/*
Was based on nutritional value and aging behavior (< 50 moves).
Sacrificing a food ration got you max luck instantly, making the
@@ -1313,10 +1308,17 @@ dosacrifice()
if (otmp->otyp == AMULET_OF_YENDOR) {
if (!highaltar) {
if (Hallucination)
You_feel("homesick.");
too_soon:
if (altaralign == A_NONE)
/* hero has left Moloch's Sanctum so is in the process
of getting away with the Amulet */
gods_upset(A_NONE);
else
You_feel("an urge to return to the surface.");
You_feel("%s.", Hallucination ? "homesick" :
/* headed towards celestial disgrace */
(altaralign != u.ualign.type) ? "ashamed" :
/* on track; give a big hint */
"an urge to return to the surface");
return 1;
} else {
/* The final Test. Did you win? */
@@ -1365,6 +1367,7 @@ verbalize("In return for thy service, I grant thee the gift of Immortality!");
} /* real Amulet */
if (otmp->otyp == FAKE_AMULET_OF_YENDOR) {
if (!highaltar && !otmp->known) goto too_soon;
if (!Deaf)
You_hear("a nearby thunderclap.");
if (!otmp->known) {
@@ -1375,6 +1378,7 @@ verbalize("In return for thy service, I grant thee the gift of Immortality!");
return 1;
} else {
/* don't you dare try to fool the gods */
if (Deaf) pline("Oh, no."); /* didn't hear thunderclap */
change_luck(-3);
adjalign(-1);
u.ugangr += 3;