From: nethack.rankin Date: Thu, 7 Sep 2006 04:42:13 +0000 (+0000) Subject: suddenly appears next to you (trunk only) X-Git-Tag: MOVE2GIT~917 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=467899e3075910ee4178167f34a24372f5102f7a;p=nethack 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 " 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 " 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. --- diff --git a/include/monst.h b/include/monst.h index b46598dd0..ba26ea924 100644 --- a/include/monst.h +++ b/include/monst.h @@ -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 diff --git a/src/makemon.c b/src/makemon.c index 655ee2c6c..9aa88aa88 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -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) diff --git a/src/minion.c b/src/minion.c index 6fd9d26b6..5d4806e65 100644 --- a/src/minion.c +++ b/src/minion.c @@ -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 diff --git a/src/mon.c b/src/mon.c index c220429c6..19f252896 100644 --- a/src/mon.c +++ b/src/mon.c @@ -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; } diff --git a/src/wizard.c b/src/wizard.c index 2ecbac909..6f0454915 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -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;