diff --git a/doc/fixes35.0 b/doc/fixes35.0 index ff4a9427d..96cd23f6d 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -106,6 +106,7 @@ wishing for particular variety of tin contents (deep fried, broiled, etc.) debug-mode wishing for random monster(s) via '*' health-food store that stocks monk-appropriate foods in mine town when monk give more information about your attributes in debug mode +polywarn to give intrinsic monster detection of limited species while polymorphed Platform- and/or Interface-Specific New Features diff --git a/include/context.h b/include/context.h index dc16cfe13..d4d4d7153 100644 --- a/include/context.h +++ b/include/context.h @@ -65,8 +65,14 @@ struct victual_info { Bitfield(doreset,1); /* stop eating at end of turn */ }; +struct warntype_info { + unsigned long obj; /* object warn_of_mon monster type M2 */ + unsigned long polyd; /* warn_of_mon monster type M2 due to poly */ + struct permonst *species; /* particular species due to poly */ + short speciesidx; /* index of above in mons[] (for save/restore) */ +}; + struct context_info { - unsigned long warntype; /* warn_of_mon monster type M2 */ unsigned ident; /* social security number for each monster */ unsigned no_of_wizards; /* 0, 1 or 2 (wizard and his shadow) */ unsigned run; /* 0: h (etc), 1: H (etc), 2: fh (etc) */ @@ -94,6 +100,7 @@ struct context_info { struct tin_info tin; struct book_info spbook; struct takeoff_info takeoff; + struct warntype_info warntype; }; extern NEARDATA struct context_info context; diff --git a/include/hack.h b/include/hack.h index 26cde3aae..ba77608c1 100644 --- a/include/hack.h +++ b/include/hack.h @@ -101,8 +101,13 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ #define FLASHED_LIGHT 3 #define INVIS_BEAM 4 -#define MATCH_WARN_OF_MON(mon) (Warn_of_mon && context.warntype && \ - (context.warntype & (mon)->data->mflags2)) +#define MATCH_WARN_OF_MON(mon) (Warn_of_mon && \ + ((context.warntype.obj && \ + (context.warntype.obj & (mon)->data->mflags2)) || \ + (context.warntype.polyd && \ + (context.warntype.polyd & (mon)->data->mflags2)) || \ + (context.warntype.species && \ + (context.warntype.species == (mon)->data)))) #include "trap.h" #include "flag.h" diff --git a/include/patchlevel.h b/include/patchlevel.h index 02d94a126..5eb92c4cb 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -13,7 +13,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 10 +#define EDITLEVEL 11 #define COPYRIGHT_BANNER_A \ "NetHack, Copyright 1985-2004" diff --git a/src/artifact.c b/src/artifact.c index dafd7db81..a071842da 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -434,10 +434,10 @@ long wp_mask; if (spec_m2(otmp)) { if (on) { EWarn_of_mon |= wp_mask; - context.warntype |= spec_m2(otmp); + context.warntype.obj |= spec_m2(otmp); } else { EWarn_of_mon &= ~wp_mask; - context.warntype &= ~spec_m2(otmp); + context.warntype.obj &= ~spec_m2(otmp); } see_monsters(); } else { diff --git a/src/cmd.c b/src/cmd.c index 13df80e2f..ffd47ec88 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -975,13 +975,29 @@ int final; /* 0 => still in progress; 1 => over, survived; 2 => dead */ from_what(SEE_INVIS)); if (Blind_telepat) you_are("telepathic",from_what(TELEPAT)); if (Warning) you_are("warned", from_what(WARNING)); - if (Warn_of_mon && context.warntype) { + if (Warn_of_mon && context.warntype.obj) { Sprintf(buf, "aware of the presence of %s", - (context.warntype & M2_ORC) ? "orcs" : - (context.warntype & M2_DEMON) ? "demons" : + (context.warntype.obj & M2_ORC) ? "orcs" : + (context.warntype.obj & M2_DEMON) ? "demons" : something); you_are(buf,from_what(WARN_OF_MON)); } + if (Warn_of_mon && context.warntype.polyd) { + Sprintf(buf, "aware of the presence of %s", + ((context.warntype.polyd & + (M2_HUMAN|M2_ELF))==(M2_HUMAN|M2_ELF)) ? "humans and elves" : + (context.warntype.polyd & M2_HUMAN) ? "humans" : + (context.warntype.polyd & M2_ELF) ? "elves" : + (context.warntype.polyd & M2_ORC) ? "orcs" : + (context.warntype.polyd & M2_DEMON) ? "demons" : + "certain monsters"); + you_are(buf,from_what(WARN_OF_MON)); + } + if (Warn_of_mon && context.warntype.speciesidx) { + Sprintf(buf, "aware of the presence of %s", + makeplural(mons[context.warntype.speciesidx].mname)); + you_are(buf,from_what(WARN_OF_MON)); + } if (Undead_warning) you_are("warned of undead",from_what(WARN_UNDEAD)); if (Searching) you_have("automatic searching",from_what(SEARCHING)); if (Clairvoyant) you_are("clairvoyant",from_what(CLAIRVOYANT)); diff --git a/src/polyself.c b/src/polyself.c index 210eded10..fa5f42967 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -18,6 +18,7 @@ STATIC_DCL void FDECL(drop_weapon,(int)); STATIC_DCL void NDECL(uunstick); STATIC_DCL int FDECL(armor_to_dragon,(int)); STATIC_DCL void NDECL(newman); +STATIC_DCL boolean FDECL(polysense,(struct permonst *)); /* update the youmonst.data structure pointer */ void @@ -205,6 +206,7 @@ dead: /* we come directly here if their experience level went to 0 or less */ Strcpy(killer.name, "unsuccessful polymorph"); done(DIED); newuhs(FALSE); + (void) polysense(youmonst.data); return; /* lifesaved */ } } @@ -216,6 +218,7 @@ dead: /* we come directly here if their experience level went to 0 or less */ Your("body transforms, but there is still slime on you."); make_slimed(10L, (const char*) 0); } + (void) polysense(youmonst.data); context.botl = 1; see_monsters(); (void) encumber_msg(); @@ -559,6 +562,8 @@ int mntmp; You("orient yourself on the web."); u.utrap = 0; } + (void) polysense(youmonst.data); + context.botl = 1; vision_full_recalc = 1; see_monsters(); @@ -1329,4 +1334,37 @@ int atyp; } } +/* + * Some species have awareness of other species + */ +static boolean +polysense(mptr) +struct permonst *mptr; +{ + short warnidx = 0; + context.warntype.speciesidx = 0; + context.warntype.species = 0; + context.warntype.polyd = 0; + + switch (monsndx(mptr)) { + case PM_PURPLE_WORM: + warnidx = PM_SHRIEKER; + break; + case PM_VAMPIRE: + case PM_VAMPIRE_LORD: + context.warntype.polyd = M2_HUMAN | M2_ELF; + HWarn_of_mon |= FROMRACE; + return TRUE; + } + if (warnidx) { + context.warntype.speciesidx = warnidx; + context.warntype.species = &mons[warnidx]; + HWarn_of_mon |= FROMRACE; + return TRUE; + } + context.warntype.speciesidx = 0; + context.warntype.species = 0; + HWarn_of_mon &= ~FROMRACE; + return FALSE; +} /*polyself.c*/ diff --git a/src/restore.c b/src/restore.c index 76fcbd3b2..f3fcc9e81 100644 --- a/src/restore.c +++ b/src/restore.c @@ -381,6 +381,9 @@ unsigned int *stuckid, *steedid; /* STEED */ return FALSE; } mread(fd, (genericptr_t) &context, sizeof(struct context_info)); + if (context.warntype.speciesidx) + context.warntype.species = &mons[context.warntype.speciesidx]; + mread(fd, (genericptr_t) &flags, sizeof(struct flag)); if (remember_discover) discover = remember_discover; #ifdef SYSFLAGS