#define ENGR_BLOOD 5
#define HEADSTONE 6
#define N_ENGRAVE 6
+ Bitfield(guardobjects, 1); /* if engr_txt is "Elbereth", it is effective
+ * against monsters when an object is present
+ * even when hero isn't (so behaves similarly
+ * to how Elbereth did in 3.4.3) */
+ /* 7 free bits */
};
#define newengr(lth) \
- (struct engr *) alloc((unsigned)(lth) + sizeof(struct engr))
-#define dealloc_engr(engr) free((genericptr_t)(engr))
+ (struct engr *) alloc((unsigned) (lth) + (unsigned) sizeof (struct engr))
+#define dealloc_engr(engr) free((genericptr_t) (engr))
#endif /* ENGRAVE_H */
extern const char *surface(coordxy, coordxy);
extern const char *ceiling(coordxy, coordxy);
extern struct engr *engr_at(coordxy, coordxy);
-extern boolean sengr_at(const char *, coordxy, coordxy, boolean);
+extern struct engr *sengr_at(const char *, coordxy, coordxy, boolean);
extern void u_wipe_engr(int);
extern void wipe_engr_at(coordxy, coordxy, xint16, boolean);
extern void read_engr_at(coordxy, coordxy);
* If strict checking is requested, the word is only considered to be
* present if it is intact and is the entire content of the engraving.
*/
-boolean
+struct engr *
sengr_at(const char *s, coordxy x, coordxy y, boolean strict)
{
- register struct engr *ep = engr_at(x, y);
+ struct engr *ep = engr_at(x, y);
if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= g.moves) {
- return (strict ? !strcmpi(ep->engr_txt, s)
- : (strstri(ep->engr_txt, s) != 0));
+ if (strict ? !strcmpi(ep->engr_txt, s)
+ : (strstri(ep->engr_txt, s) != 0))
+ return ep;
}
- return FALSE;
+ return (struct engr *) NULL;
}
void
if ((ep = engr_at(x, y)) != 0)
del_engr(ep);
ep = newengr(smem);
- (void) memset((genericptr_t)ep, 0, smem + sizeof(struct engr));
+ (void) memset((genericptr_t) ep, 0, smem + sizeof (struct engr));
ep->nxt_engr = head_engr;
head_engr = ep;
ep->engr_x = x;
ep->engr_y = y;
ep->engr_txt = (char *) (ep + 1);
Strcpy(ep->engr_txt, s);
- /* engraving Elbereth shows wisdom */
- if (!g.in_mklev && !strcmp(s, "Elbereth"))
- exercise(A_WIS, TRUE);
+ if (!strcmp(s, "Elbereth")) {
+ /* engraving "Elbereth": if done when making a level, it creates
+ an old-style Elbereth that deters monsters when any objects are
+ present; otherwise (done by the player), exercises wisdom */
+ if (g.in_mklev)
+ ep->guardobjects = 1;
+ else
+ exercise(A_WIS, TRUE);
+ }
ep->engr_time = e_time;
ep->engr_type = e_type > 0 ? e_type : rnd(N_ENGRAVE - 1);
ep->engr_lth = smem;
}
boolean
-onscary(coordxy x, coordxy y, struct monst* mtmp)
+onscary(coordxy x, coordxy y, struct monst *mtmp)
{
+ struct engr *ep;
+
/* creatures who are directly resistant to magical scaring:
* humans aren't monsters
* uniques have ascended their base monster instincts
* Elbereth doesn't work in Gehennom, the Elemental Planes, or the
* Astral Plane; the influence of the Valar only reaches so far.
*/
- return (sengr_at("Elbereth", x, y, TRUE)
- && (u_at(x, y) || (Displaced && mtmp->mux == x && mtmp->muy == y))
+ return ((ep = sengr_at("Elbereth", x, y, TRUE)) != 0
+ && (u_at(x, y)
+ || (Displaced && mtmp->mux == x && mtmp->muy == y)
+ || (ep->guardobjects && vobj_at(x, y)))
&& !(mtmp->isshk || mtmp->isgd || !mtmp->mcansee
|| mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN
|| mtmp->data == &mons[PM_MINOTAUR]
|| Inhell || In_endgame(&u.uz)));
}
-
/* regenerate lost hit points */
void
mon_regen(struct monst *mon, boolean digest_meal)
}
/* this is an approximation of onscary() that doesn't use any 'struct monst'
- fields aside from 'monst->data' */
+ fields aside from 'monst->data'; used primarily for new monster creation
+ and monster teleport destination, not for ordinary monster movement */
static boolean
goodpos_onscary(
coordxy x, coordxy y,
/* engraved Elbereth doesn't work in Gehennom or the end-game */
if (Inhell || In_endgame(&u.uz))
return FALSE;
- /* creatures who don't (or can't) fear a written Elbereth */
+ /* creatures who don't (or can't) fear a written Elbereth and weren't
+ caught by the minions check */
if (mptr == &mons[PM_MINOTAUR] || !haseyes(mptr))
return FALSE;
- return sengr_at("Elbereth", x, y, TRUE);
+ return sengr_at("Elbereth", x, y, TRUE) ? TRUE : FALSE;
}
/*