diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 415f28efa..f81095323 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -213,6 +213,7 @@ some monsters can eat tins in addition to corpses to cure some ailments add Roderick Schertler's pickup_thrown patch add ability to sort the list when viewing known spells with '+' command describe magic cancellation from worn armor in enlightment/end-of-game feedback +add atmospheric sound messages for temples Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index a5ac7055a..f058e69dc 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1709,6 +1709,7 @@ E void FDECL(altar_wrath, (int,int)); E int FDECL(move_special, (struct monst *,BOOLEAN_P,SCHAR_P,BOOLEAN_P,BOOLEAN_P, XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P)); E char FDECL(temple_occupied, (char *)); +E boolean FDECL(inhistemple, (struct monst *)); E int FDECL(pri_move, (struct monst *)); E void FDECL(priestini, (d_level *,struct mkroom *,int,int,BOOLEAN_P)); E aligntyp FDECL(mon_aligntyp, (struct monst *)); diff --git a/src/priest.c b/src/priest.c index 1ebec98cd..ee43c80e0 100644 --- a/src/priest.c +++ b/src/priest.c @@ -148,6 +148,18 @@ register xchar x, y; on_level(&(EPRI(priest)->shrlevel), &u.uz))); } +boolean +inhistemple(priest) +struct monst *priest; +{ + /* make sure we have a priest */ + if (!priest || !priest->ispriest) return FALSE; + /* priest must be on right level and in right room */ + if (!histemple_at(priest, priest->mx, priest->my)) return FALSE; + /* temple room must still contain properly aligned altar */ + return has_shrine(priest); +} + /* * pri_move: return 1: moved 0: didn't -1: let m_move do it -2: died */ @@ -322,7 +334,7 @@ struct monst *pri; struct rm *lev; struct epri *epri_p; - if (!pri) return FALSE; + if (!pri || !pri->ispriest) 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; diff --git a/src/sounds.c b/src/sounds.c index ddc202d4e..542a0ab94 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -234,11 +234,59 @@ dosounds() } return; } + if (level.flags.has_temple && !rn2(200) && + !(Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) { + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp)) continue; + if (mtmp->ispriest && inhistemple(mtmp) && + /* priest must be active */ + mtmp->mcanmove && !mtmp->msleeping && + /* hero must be outside this temple */ + temple_occupied(u.urooms) != EPRI(mtmp)->shroom) + break; + } + if (mtmp) { + /* Generic temple messages; no attempt to match topic or tone + to the pantheon involved, let alone to the specific deity. + These are assumed to be coming from the attending priest; + asterisk means that the priest must be capable of speech; + pound sign (octathorpe,&c--don't go there) means that the + priest and the altar must not be directly visible (we don't + care if telepathy or extended detection reveals that the + priest is not currently standing on the altar; he's mobile). */ + static const char * const temple_msg[] = { + "*someone praising %s.", + "*someone beseeching %s.", + "#an animal carcass being offered in sacrifice.", + "*a strident plea for donations.", + }; + const char *msg; + int idx, trycount = 0, + ax = EPRI(mtmp)->shrpos.x, ay = EPRI(mtmp)->shrpos.y; + boolean speechless = (mtmp->data->msound <= MS_ANIMAL), + in_sight = canseemon(mtmp) || cansee(ax, ay); + + do { + msg = temple_msg[rn2(SIZE(temple_msg) - 1 + hallu)]; + if (index(msg, '*') && speechless) continue; + if (index(msg, '#') && in_sight) continue; + break; /* msg is acceptable */ + } while (++trycount < 50); + while (!letter(*msg)) ++msg; /* skip control flags */ + if (index(msg, '%')) + You_hear(msg, halu_gname(EPRI(mtmp)->shralign)); + else + You_hear(msg); + return; + } + } if (Is_oracle_level(&u.uz) && !rn2(400)) { /* make sure the Oracle is still here */ - for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) - if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_ORACLE]) + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp)) continue; + if (mtmp->data == &mons[PM_ORACLE]) break; + } /* and don't produce silly effects when she's clearly visible */ if (mtmp && (hallu || !canseemon(mtmp))) { static const char * const ora_msg[5] = {