<foo> suddenly appears next to you (trunk only)

Give demon lords and other monsters who teleport to your location a
oneshot arrival message.  Brought about by the report of the late "<demon>
appears" message delivered during its bribery demand, after the character
had already been able to see it for long enough to extract gold from a bag.
Now, if you can't see or sense a monster before it teleports to you, and
you can see or sense it after, you'll get "<monster> suddenly appears!".
The message will be given at most once for any given monster, and it won't
be shown at all if you already see/sense the monster before it teleports or
still don't see/sense it afterwards.  The fixes entry is deliberately a bit
vague (and I put it in the new feature section rather than the fix section).

     The change from long to unsigned long for monst.mstrategy may bring
some lint complaints along with it.  The various constants (STRAT_xxx) used
to populate it are still signed.  I didn't increment EDITLEVEL for this;
existing data should still work ok.
This commit is contained in:
nethack.rankin
2006-09-07 04:42:13 +00:00
parent 4c4304cc62
commit 467899e307
5 changed files with 53 additions and 29 deletions

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)monst.h 3.5 2006/01/02 */
/* SCCS Id: @(#)monst.h 3.5 2006/09/06 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -108,11 +108,16 @@ struct monst {
#define MAX_NUM_WORMS 32 /* should be 2^(wormno bitfield size) */
long mstrategy; /* for monsters with mflag3: current strategy */
unsigned long mstrategy; /* for monsters with mflag3: current strategy */
#ifdef NHSTDC
#define STRAT_APPEARMSG 0x80000000UL
#else
#define STRAT_APPEARMSG 0x80000000L
#endif
#define STRAT_ARRIVE 0x40000000L /* just arrived on current level */
#define STRAT_WAITFORU 0x20000000L
#define STRAT_CLOSE 0x10000000L
#define STRAT_WAITMASK 0x30000000L
#define STRAT_WAITMASK (STRAT_CLOSE | STRAT_WAITFORU)
#define STRAT_HEAL 0x08000000L
#define STRAT_GROUND 0x04000000L
#define STRAT_MONSTR 0x02000000L

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)makemon.c 3.5 2006/07/08 */
/* SCCS Id: @(#)makemon.c 3.5 2006/09/06 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1136,11 +1136,13 @@ register int mmflags;
if (mtmp->minvent) discard_minvent(mtmp);
mtmp->minvent = (struct obj *)0; /* caller expects this */
}
if ((ptr->mflags3 & M3_WAITMASK) && !(mmflags & MM_NOWAIT)) {
if (ptr->mflags3 & M3_WAITFORU)
mtmp->mstrategy |= STRAT_WAITFORU;
if (ptr->mflags3 & M3_CLOSE)
mtmp->mstrategy |= STRAT_CLOSE;
if (ptr->mflags3 && !(mmflags & MM_NOWAIT)) {
if (ptr->mflags3 & M3_WAITFORU)
mtmp->mstrategy |= STRAT_WAITFORU;
if (ptr->mflags3 & M3_CLOSE)
mtmp->mstrategy |= STRAT_CLOSE;
if (ptr->mflags3 & (M3_WAITMASK|M3_COVETOUS))
mtmp->mstrategy |= STRAT_APPEARMSG;
}
if (!in_mklev)

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)minion.c 3.5 2006/01/03 */
/* SCCS Id: @(#)minion.c 3.5 2006/09/06 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -163,6 +163,7 @@ boolean talk;
verbalize("Thou shalt pay for thine indiscretion!");
if (!Blind)
pline("%s appears before you.", Amonnam(mon));
mon->mstrategy &= ~STRAT_APPEARMSG;
}
mon->mpeaceful = FALSE;
/* don't call set_malign(); player was naughty */
@@ -194,8 +195,13 @@ register struct monst *mtmp;
/* Slight advantage given. */
if (is_dprince(mtmp->data) && mtmp->minvis) {
boolean wasunseen = !canspotmon(mtmp);
mtmp->minvis = mtmp->perminvis = 0;
if (!Blind) pline("%s appears before you.", Amonnam(mtmp));
if (wasunseen && canspotmon(mtmp)) {
pline("%s appears before you.", Amonnam(mtmp));
mtmp->mstrategy &= ~STRAT_APPEARMSG;
}
newsym(mtmp->mx,mtmp->my);
}
if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
@@ -411,6 +417,7 @@ gain_guardian_angel()
if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]) &&
(mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type,
mm.x, mm.y, TRUE)) != 0) {
mtmp->mstrategy &= ~STRAT_APPEARMSG;
if (!Blind)
pline("An angel appears near you.");
else

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mon.c 3.5 2006/07/08 */
/* SCCS Id: @(#)mon.c 3.5 2006/09/06 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2063,6 +2063,7 @@ mnexto(mtmp) /* Make monster mtmp next to you (if possible) */
struct monst *mtmp;
{
coord mm;
boolean couldspot = canspotmon(mtmp);
#ifdef STEED
if (mtmp == u.usteed) {
@@ -2075,6 +2076,12 @@ mnexto(mtmp) /* Make monster mtmp next to you (if possible) */
if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return;
rloc_to(mtmp, mm.x, mm.y);
if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) {
mtmp->mstrategy &= ~STRAT_APPEARMSG; /* one chance only */
if (!couldspot && canspotmon(mtmp))
pline("%s suddenly %s!", Amonnam(mtmp),
!Blind ? "appears" : "arrives");
}
return;
}

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)wizard.c 3.5 2005/10/05 */
/* SCCS Id: @(#)wizard.c 3.5 2006/09/06 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -17,8 +17,8 @@ STATIC_DCL boolean FDECL(mon_has_arti, (struct monst *,SHORT_P));
STATIC_DCL struct monst *FDECL(other_mon_has_arti, (struct monst *,SHORT_P));
STATIC_DCL struct obj *FDECL(on_ground, (SHORT_P));
STATIC_DCL boolean FDECL(you_have, (int));
STATIC_DCL long FDECL(target_on, (int,struct monst *));
STATIC_DCL long FDECL(strategy, (struct monst *));
STATIC_DCL unsigned long FDECL(target_on, (int,struct monst *));
STATIC_DCL unsigned long FDECL(strategy, (struct monst *));
static NEARDATA const int nasties[] = {
PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON,
@@ -121,7 +121,8 @@ register struct monst *mtmp;
* The strategy section decides *what* the monster is going
* to attempt, the tactics section implements the decision.
*/
#define STRAT(w, x, y, typ) (w | ((long)(x)<<16) | ((long)(y)<<8) | (long)typ)
#define STRAT(w,x,y,typ) ((unsigned long)(w) | ((unsigned long)(x) << 16) | \
((unsigned long)(y) << 8) | (unsigned long)(typ))
#define M_Wants(mask) (mtmp->data->mflags3 & (mask))
@@ -207,7 +208,7 @@ you_have(mask)
return(0);
}
STATIC_OVL long
STATIC_OVL unsigned long
target_on(mask, mtmp)
register int mask;
register struct monst *mtmp;
@@ -216,7 +217,7 @@ target_on(mask, mtmp)
register struct obj *otmp;
register struct monst *mtmp2;
if(!M_Wants(mask)) return(STRAT_NONE);
if (!M_Wants(mask)) return (unsigned long)STRAT_NONE;
otyp = which_arti(mask);
if(!mon_has_arti(mtmp, otyp)) {
@@ -227,31 +228,33 @@ target_on(mask, mtmp)
else if((mtmp2 = other_mon_has_arti(mtmp, otyp)))
return(STRAT(STRAT_MONSTR, mtmp2->mx, mtmp2->my, mask));
}
return(STRAT_NONE);
return (unsigned long)STRAT_NONE;
}
STATIC_OVL long
STATIC_OVL unsigned long
strategy(mtmp)
register struct monst *mtmp;
{
long strat, dstrat;
unsigned long strat, dstrat;
if (!is_covetous(mtmp->data) ||
/* perhaps a shopkeeper has been polymorphed into a master
lich; we don't want it teleporting to the stairs to heal
because that will leave its shop untended */
(mtmp->isshk && inhishop(mtmp)))
return STRAT_NONE;
(mtmp->isshk && inhishop(mtmp)) ||
/* likewise for temple priests */
(mtmp->ispriest && inhistemple(mtmp)))
return (unsigned long)STRAT_NONE;
switch((mtmp->mhp*3)/mtmp->mhpmax) { /* 0-3 */
default:
case 0: /* panic time - mtmp is almost snuffed */
return(STRAT_HEAL);
return (unsigned long)(STRAT_HEAL);
case 1: /* the wiz is less cautious */
if(mtmp->data != &mons[PM_WIZARD_OF_YENDOR])
return(STRAT_HEAL);
return (unsigned long)(STRAT_HEAL);
/* else fall through */
case 2: dstrat = STRAT_HEAL;
@@ -293,9 +296,9 @@ int
tactics(mtmp)
register struct monst *mtmp;
{
long strat = strategy(mtmp);
unsigned long strat = strategy(mtmp);
mtmp->mstrategy = (mtmp->mstrategy & STRAT_WAITMASK) | strat;
mtmp->mstrategy = (mtmp->mstrategy & (STRAT_WAITMASK|STRAT_APPEARMSG)) | strat;
switch (strat) {
case STRAT_HEAL: /* hide and recover */
@@ -326,7 +329,7 @@ tactics(mtmp)
long where = (strat & STRAT_STRATMASK);
xchar tx = STRAT_GOALX(strat),
ty = STRAT_GOALY(strat);
int targ = strat & STRAT_GOAL;
int targ = (int)(strat & STRAT_GOAL);
struct obj *otmp;
if(!targ) { /* simply wants you to close */
@@ -374,7 +377,7 @@ aggravate()
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) continue;
mtmp->mstrategy &= ~STRAT_WAITFORU;
mtmp->mstrategy &= ~(STRAT_WAITFORU|STRAT_APPEARMSG);
mtmp->msleeping = 0;
if (!mtmp->mcanmove && !rn2(5)) {
mtmp->mfrozen = 0;