reduce temple verbosity (trunk only)

Cut down on the excessive verbosity generated when entering a temple.
The first time you enter a particular temple (or more accurately, the
temple attended by a particular priest), you still get the three message
sequence
  The <priest of foo> intones:
  Pilgrim, you enter a sacred place!
  You have a strange forbidding feeling...
or
  You experience a strange sense of peace.
except that the last one doesn't say "strange" any more.  On subsequent
visits to the same temple, you usually won't get the first introductory
message any more, often won't get the second entry one, and sometimes
won't even get the final one, depending upon how much time has elapsed
since the previous entry.  The old verbosity could really be infuriating
when attempting to lug corpses to the altar before they spoil.  Even
though the messages don't affect the passage of time, it always felt as
if they were slowing you down.  And even when you weren't in any hurry,
it required at least one and often 2 or even 3 responses to --More--
depending upon the length of the deity's name and whether some other
message was also delivered on the same turn (fairly common in minetown).

     Saving and restoring, or leaving the level and returning, resets
the priest's memory of when the messages were last given, so the next
entry after that behaves similar to the very first.  This was initially
intended for cleanup prior to saving bones data, but it seemed reasonable
to have it apply to the current game too.  Unattended temples now also
have a 25% chance of not giving any message when entering.  That one is
random rather than based on the passage of time since last entry; there's
no priest available to track the latter data.
This commit is contained in:
nethack.rankin
2006-01-28 06:46:19 +00:00
parent ec26550fcc
commit 0a52d1879f
7 changed files with 142 additions and 80 deletions

View File

@@ -108,6 +108,7 @@ fix wording for "leprechaun steals gold from between your feet" when mounted
fix monsndx panic which happened after currently moving monster expelled
swallowed hero onto magic trap and was made tame by its effect; taming
no longer replaces monster
reduced message verbosity when re-entering a temple
Platform- and/or Interface-Specific Fixes

View File

@@ -1686,6 +1686,7 @@ E char *FDECL(priestname, (struct monst *,char *));
E boolean FDECL(p_coaligned, (struct monst *));
E struct monst *FDECL(findpriest, (CHAR_P));
E void FDECL(intemple, (int));
E void FDECL(forget_temple_entry, (struct monst *));
E void FDECL(priest_talk, (struct monst *));
E struct monst *FDECL(mk_roamer, (struct permonst *,ALIGNTYP_P,
XCHAR_P,XCHAR_P,BOOLEAN_P));

View File

@@ -86,6 +86,10 @@ struct epri {
schar shroom; /* index in rooms */
coord shrpos; /* position of shrine */
d_level shrlevel; /* level (& dungeon) of shrine */
long intone_time, /* used to limit verbosity +*/
enter_time, /*+ of temple entry messages */
hostile_time, /* forbidding feeling */
peaceful_time; /* sense of peace */
};
/* note: roaming priests (no shrine) switch from ispriest to isminion
(and emin extension) */

View File

@@ -13,7 +13,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 25
#define EDITLEVEL 26
#define COPYRIGHT_BANNER_A \
"NetHack, Copyright 1985-2006"

View File

@@ -1074,6 +1074,7 @@ struct monst *mtmp;
int lth, namelth;
namelth = obj->onamelth ? strlen(ONAME(obj)) + 1 : 0;
if (mtmp->ispriest) forget_temple_entry(mtmp); /* EPRI() */
buffer = mon_to_buffer(mtmp, &lth);
otmp = realloc_obj(obj, lth, buffer, namelth, ONAME(obj));
free(buffer);

View File

@@ -5,8 +5,9 @@
#include "hack.h"
#include "mfndpos.h"
/* this matches the categorizations shown by enlightenment */
#define ALGN_SINNED (-4) /* worse than strayed */
/* these match the categorizations shown by enlightenment */
#define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
#define ALGN_PIOUS 14 /* better than fervent (9..13) */
STATIC_DCL boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
STATIC_DCL boolean FDECL(has_shrine,(struct monst *));
@@ -317,13 +318,14 @@ has_shrine(pri)
struct monst *pri;
{
struct rm *lev;
struct epri *epri_p;
if(!pri)
return(FALSE);
lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
return(FALSE);
return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
if (!pri) return FALSE;
epri_p = EPRI(pri);
lev = &levl[epri_p->shrpos.x][epri_p->shrpos.y];
if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE)) return FALSE;
return (boolean)(epri_p->shralign ==
(Amask2align(lev->altarmask & ~AM_SHRINE)));
}
struct monst *
@@ -344,81 +346,133 @@ char roomno;
/* called from check_special_room() when the player enters the temple room */
void
intemple(roomno)
register int roomno;
int roomno;
{
register struct monst *priest = findpriest((char)roomno);
boolean tended = (priest != (struct monst *)0);
boolean shrined, sanctum, can_speak;
const char *msg1, *msg2;
char buf[BUFSZ];
struct monst *priest, *mtmp;
struct epri *epri_p;
boolean shrined, sanctum, can_speak;
long *this_time, *other_time;
const char *msg1, *msg2;
char buf[BUFSZ];
if(!temple_occupied(u.urooms0)) {
if(tended) {
shrined = has_shrine(priest);
sanctum = (priest->data == &mons[PM_HIGH_PRIEST] &&
(Is_sanctum(&u.uz) || In_endgame(&u.uz)));
can_speak = (priest->mcanmove && !priest->msleeping &&
!Deaf);
if (can_speak) {
unsigned save_priest = priest->ispriest;
/* don't reveal the altar's owner upon temple entry in
the endgame; for the Sanctum, the next message names
Moloch so suppress the "of Moloch" for him here too */
if (sanctum && !Hallucination) priest->ispriest = 0;
pline("%s intones:",
canseemon(priest) ? Monnam(priest) : "A nearby voice");
priest->ispriest = save_priest;
}
msg2 = 0;
if(sanctum && Is_sanctum(&u.uz)) {
if(priest->mpeaceful) {
msg1 = "Infidel, you have entered Moloch's Sanctum!";
msg2 = "Be gone!";
priest->mpeaceful = 0;
set_malign(priest);
} else
msg1 = "You desecrate this place by your presence!";
} else {
Sprintf(buf, "Pilgrim, you enter a %s place!",
!shrined ? "desecrated" : "sacred");
msg1 = buf;
}
if (can_speak) {
verbalize(msg1);
if (msg2) verbalize(msg2);
}
if(!sanctum) {
/* !tended -> !shrined */
if (!shrined || !p_coaligned(priest) ||
u.ualign.record <= ALGN_SINNED)
You("have a%s forbidding feeling...",
(!shrined) ? "" : " strange");
else You("experience a strange sense of peace.");
}
/* don't do anything if hero is already in the room */
if (temple_occupied(u.urooms0)) return;
if ((priest = findpriest((char)roomno)) != 0) {
/* tended */
epri_p = EPRI(priest);
shrined = has_shrine(priest);
sanctum = (priest->data == &mons[PM_HIGH_PRIEST] &&
(Is_sanctum(&u.uz) || In_endgame(&u.uz)));
can_speak = (priest->mcanmove && !priest->msleeping);
if (can_speak && !Deaf && moves >= epri_p->intone_time) {
unsigned save_priest = priest->ispriest;
/* don't reveal the altar's owner upon temple entry in
the endgame; for the Sanctum, the next message names
Moloch so suppress the "of Moloch" for him here too */
if (sanctum && !Hallucination) priest->ispriest = 0;
pline("%s intones:",
canseemon(priest) ? Monnam(priest) : "A nearby voice");
priest->ispriest = save_priest;
epri_p->intone_time = moves + (long)d(10, 500); /* ~2505 */
/* make sure that we don't suppress entry message when
we've just given its "priest intones" introduction */
epri_p->enter_time = 0L;
}
msg1 = msg2 = 0;
if (sanctum && Is_sanctum(&u.uz)) {
if (priest->mpeaceful) {
/* first time inside */
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);
} else {
switch(rn2(3)) {
case 0: You("have an eerie feeling..."); break;
case 1: You_feel("like you are being watched."); break;
default: pline("A shiver runs down your %s.",
body_part(SPINE)); break;
}
if(!rn2(5)) {
struct monst *mtmp;
/* repeat visit, or attacked priest before entering */
msg1 = "You desecrate this place by your presence!";
}
} else if (moves >= epri_p->enter_time) {
Sprintf(buf, "Pilgrim, you enter a %s place!",
!shrined ? "desecrated" : "sacred");
msg1 = buf;
}
if (msg1 && can_speak && !Deaf) {
verbalize(msg1);
if (msg2) verbalize(msg2);
epri_p->enter_time = moves + (long)d(10, 100); /* ~505 */
}
if (!sanctum) {
if (!shrined || !p_coaligned(priest) ||
u.ualign.record <= ALGN_SINNED) {
msg1 = "have a%s forbidding feeling...";
msg2 = (!shrined || !p_coaligned(priest)) ? "" : " strange";
this_time = &epri_p->hostile_time;
other_time = &epri_p->peaceful_time;
} else {
msg1 = "experience %s sense of peace.";
msg2 = (u.ualign.record >= ALGN_PIOUS) ? "a" : "an unusual";
this_time = &epri_p->peaceful_time;
other_time = &epri_p->hostile_time;
}
/* give message if we haven't seen it recently or
if alignment update has caused it to switch from
forbidding to sense-of-peace or vice versa */
if (moves >= *this_time || *other_time >= *this_time) {
You(msg1, msg2);
*this_time = moves + (long)d(10, 20); /* ~55 */
/* avoid being tricked by the RNG: switch might have just
happened and previous random threshold could be larger */
if (*this_time <= *other_time) *other_time = *this_time - 1L;
}
}
} else {
/* untended */
if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy,NO_MM_FLAGS)))
return;
if (!Blind || sensemon(mtmp))
pline("An enormous ghost appears next to you!");
else You("sense a presence close by!");
mtmp->mpeaceful = 0;
set_malign(mtmp);
if(flags.verbose)
You("are frightened to death, and unable to move.");
nomul(-3);
nomovemsg = "You regain your composure.";
}
}
}
switch (rn2(4)) {
case 0: You("have an eerie feeling..."); break;
case 1: You_feel("like you are being watched."); break;
case 2: pline("A shiver runs down your %s.",
body_part(SPINE)); break;
default: break; /* no message; unfortunately there's no
EPRI(priest)->eerie_time available to
make sure we give one the first time */
}
if (!rn2(5) &&
(mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS)) != 0) {
/* [TODO: alter this (at a minimum, by switching from
an exclamation to a simple declaration) if hero has
already killed enough ghosts.] */
if (canspotmon(mtmp))
pline("An enormous ghost appears next to you!");
else
You("sense a presence close by!");
mtmp->mpeaceful = 0;
set_malign(mtmp);
if (flags.verbose)
You("are frightened to death, and unable to move.");
nomul(-3);
nomovemsg = "You regain your composure.";
}
}
}
/* reset the move counters used to limit temple entry feedback;
leaving the level and then returning yields a fresh start */
void
forget_temple_entry(priest)
struct monst *priest;
{
struct epri *epri_p = priest->ispriest ? EPRI(priest) : 0;
if (!epri_p) {
impossible("attempting to manipulate shrine data for non-priest?");
return;
}
epri_p->intone_time = epri_p->enter_time =
epri_p->peaceful_time = epri_p->hostile_time = 0L;
}
void

View File

@@ -1093,6 +1093,7 @@ register struct monst *mtmp;
mtmp2 = mtmp->nmon;
if (perform_bwrite(mode)) {
mtmp->mnum = monsndx(mtmp->data);
if (mtmp->ispriest) forget_temple_entry(mtmp); /* EPRI() */
#ifndef GOLDOBJ
if (mtmp->mgold) {
struct obj *goldobj = mksobj(GOLD_PIECE, FALSE, FALSE);