polywarn (trunk only)

This patch increments editlevel making existing save and bones files useless.

Add polywarn() code to grant the ability to detect certain monster
types while polymorphed into other specific monster types.

If you polymorph into a vampire or vampire lord, you are able to
sense humans.

And just for fun, if you polymorph into a purple worm, you are able to
sense shriekers :-)
This commit is contained in:
nethack.allison
2004-06-03 04:20:13 +00:00
parent f327a370fd
commit 6644c4086f
8 changed files with 79 additions and 9 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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"

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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));

View File

@@ -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*/

View File

@@ -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