monsters moving other monsters (trunk only)
For now, the code is conditional on BARGETHROUGH being defined, while it gets tested further. While behavior is different with and without BARGETHROUGH defined, savefiles are the same either way. After this patch is applied, only the riders have the M3_DISPLACES bit set, but the Wizard and Vlad probably should too. Any others?
This commit is contained in:
@@ -335,6 +335,7 @@ typedef unsigned char uchar;
|
||||
#if !defined(MAC)
|
||||
# define CLIPPING /* allow smaller screens -- ERS */
|
||||
#endif
|
||||
#define BARGETHROUGH /* allow some monster to move others out of their way */
|
||||
|
||||
#ifdef REDO
|
||||
# define DOAGAIN '\001' /* ^A, the "redo" key used in cmd.c and getline.c */
|
||||
|
||||
@@ -463,6 +463,9 @@ E void FDECL(switch_graphics, (int));
|
||||
#ifdef REINCARNATION
|
||||
E void FDECL(assign_rogue_graphics, (BOOLEAN_P));
|
||||
#endif
|
||||
#ifdef BARGETHROUGH
|
||||
E boolean FDECL(cursed_object_at, (int, int));
|
||||
#endif
|
||||
|
||||
/* ### dungeon.c ### */
|
||||
|
||||
@@ -966,6 +969,9 @@ E int FDECL(buzzmu, (struct monst *,struct attack *));
|
||||
|
||||
E int FDECL(fightm, (struct monst *));
|
||||
E int FDECL(mattackm, (struct monst *,struct monst *));
|
||||
#ifdef BARGETHROUGH
|
||||
E int FDECL(mdisplacem, (struct monst *,struct monst *,BOOLEAN_P));
|
||||
#endif
|
||||
E int FDECL(noattacks, (struct permonst *));
|
||||
E int FDECL(sleep_monst, (struct monst *,int,int));
|
||||
E void FDECL(slept_monst, (struct monst *));
|
||||
@@ -1216,6 +1222,11 @@ E boolean FDECL(closed_door, (int,int));
|
||||
E boolean FDECL(accessible, (int,int));
|
||||
E void FDECL(set_apparxy, (struct monst *));
|
||||
E boolean FDECL(can_ooze, (struct monst *));
|
||||
#ifdef BARGETHROUGH
|
||||
E boolean FDECL(should_displace, (struct monst *,coord *,long *,int,
|
||||
XCHAR_P,XCHAR_P));
|
||||
E boolean FDECL(undesirable_disp, (struct monst *,XCHAR_P,XCHAR_P));
|
||||
#endif
|
||||
|
||||
/* ### monst.c ### */
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#ifndef MFNDPOS_H
|
||||
#define MFNDPOS_H
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
#define ALLOW_MDISP 0x00001000L /* can displace a monster out of its way */
|
||||
#endif
|
||||
#define ALLOW_TRAPS 0x00020000L /* can enter traps */
|
||||
#define ALLOW_U 0x00040000L /* can attack you */
|
||||
#define ALLOW_M 0x00080000L /* can attack other monsters */
|
||||
|
||||
@@ -129,6 +129,9 @@
|
||||
#define is_covetous(ptr) ((ptr->mflags3 & M3_COVETOUS))
|
||||
#define infravision(ptr) ((ptr->mflags3 & M3_INFRAVISION))
|
||||
#define infravisible(ptr) ((ptr->mflags3 & M3_INFRAVISIBLE))
|
||||
#ifdef BARGETHROUGH
|
||||
#define is_displacer(ptr) (((ptr)->mflags3 & M3_DISPLACES) != 0L)
|
||||
#endif
|
||||
#define is_mplayer(ptr) (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \
|
||||
((ptr) <= &mons[PM_WIZARD]))
|
||||
#define is_rider(ptr) ((ptr) == &mons[PM_DEATH] || \
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
#define M3_INFRAVISION 0x0100 /* has infravision */
|
||||
#define M3_INFRAVISIBLE 0x0200 /* visible by infravision */
|
||||
|
||||
/* define the bit even if BARGETHROUGH is not defined for savefile compat. */
|
||||
#define M3_DISPLACES 0x0400 /* moves monsters out of its way */
|
||||
|
||||
#define MZ_TINY 0 /* < 2' */
|
||||
#define MZ_SMALL 1 /* 2-4' */
|
||||
#define MZ_MEDIUM 2 /* 4-7' */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||
* and save files.
|
||||
*/
|
||||
#define EDITLEVEL 7
|
||||
#define EDITLEVEL 8
|
||||
|
||||
#define COPYRIGHT_BANNER_A \
|
||||
"NetHack, Copyright 1985-2003"
|
||||
|
||||
@@ -48,13 +48,19 @@ register struct monst *mon;
|
||||
|
||||
static NEARDATA const char nofetch[] = { BALL_CLASS, CHAIN_CLASS, ROCK_CLASS, 0 };
|
||||
|
||||
#ifndef BARGETHROUGH
|
||||
STATIC_OVL boolean FDECL(cursed_object_at, (int, int));
|
||||
#endif /* not BARGETHROUGH */
|
||||
|
||||
STATIC_VAR xchar gtyp, gx, gy; /* type and position of dog's current goal */
|
||||
|
||||
STATIC_PTR void FDECL(wantdoor, (int, int, genericptr_t));
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
boolean
|
||||
#else
|
||||
STATIC_OVL boolean
|
||||
#endif
|
||||
cursed_object_at(x, y)
|
||||
int x, y;
|
||||
{
|
||||
@@ -489,6 +495,9 @@ register int after; /* this is extra fast monster movement */
|
||||
struct obj *obj = (struct obj *) 0;
|
||||
xchar otyp;
|
||||
boolean has_edog, cursemsg[9], do_eat = FALSE;
|
||||
#ifdef BARGETHROUGH
|
||||
boolean better_with_displacing = FALSE;
|
||||
#endif
|
||||
xchar nix, niy; /* position mtmp is (considering) moving to */
|
||||
register int nx, ny; /* temporary coordinates */
|
||||
xchar cnt, uncursedcnt, chcnt;
|
||||
@@ -546,6 +555,9 @@ register int after; /* this is extra fast monster movement */
|
||||
if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK | ALLOW_WALL);
|
||||
if (passes_bars(mtmp->data)) allowflags |= ALLOW_BARS;
|
||||
if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
|
||||
#ifdef BARGETHROUGH
|
||||
if (is_displacer(mtmp->data)) allowflags |= ALLOW_MDISP;
|
||||
#endif
|
||||
if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
|
||||
allowflags |= ALLOW_U;
|
||||
if (!has_edog) {
|
||||
@@ -590,11 +602,20 @@ register int after; /* this is extra fast monster movement */
|
||||
uncursedcnt = 0;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
nx = poss[i].x; ny = poss[i].y;
|
||||
#ifdef BARGETHROUGH
|
||||
if (MON_AT(nx,ny) && !((info[i] & ALLOW_M) || info[i] & ALLOW_MDISP))
|
||||
continue;
|
||||
#else
|
||||
if (MON_AT(nx,ny) && !(info[i] & ALLOW_M)) continue;
|
||||
#endif
|
||||
if (cursed_object_at(nx, ny)) continue;
|
||||
uncursedcnt++;
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
better_with_displacing = should_displace(mtmp,poss,info,cnt,gx,gy);
|
||||
#endif
|
||||
|
||||
chcnt = 0;
|
||||
chi = -1;
|
||||
nidist = GDIST(nix,niy);
|
||||
@@ -645,9 +666,19 @@ register int after; /* this is extra fast monster movement */
|
||||
mstatus = mattackm(mtmp2, mtmp); /* return attack */
|
||||
if (mstatus & MM_DEF_DIED) return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef BARGETHROUGH
|
||||
if ((info[i] & ALLOW_MDISP) && MON_AT(nx, ny) &&
|
||||
better_with_displacing &&
|
||||
!undesirable_disp(mtmp,nx,ny)) {
|
||||
int mstatus;
|
||||
register struct monst *mtmp2 = m_at(nx,ny);
|
||||
mstatus = mdisplacem(mtmp, mtmp2, FALSE); /* displace monster */
|
||||
if (mstatus && MM_DEF_DIED) return 2;
|
||||
return 0;
|
||||
}
|
||||
#endif /* BARGETHROUGH */
|
||||
|
||||
{ /* Dog avoids harmful traps, but perhaps it has to pass one
|
||||
* in order to follow player. (Non-harmful traps do not
|
||||
|
||||
111
src/mhitm.c
111
src/mhitm.c
@@ -168,10 +168,9 @@ fightm(mtmp) /* have monsters fight each other */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
/*
|
||||
* mattackm() -- a monster attacks another monster.
|
||||
*
|
||||
* This function returns a result bitfield:
|
||||
* mattackm() and mdisplacem() below both return a result bitfield:
|
||||
*
|
||||
* --------- aggressor died
|
||||
* / ------- defender died
|
||||
@@ -184,6 +183,112 @@ fightm(mtmp) /* have monsters fight each other */
|
||||
* 0x1 MM_HIT
|
||||
* 0x0 MM_MISS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* mdisplacem() -- a monster moves another monster out of the way.
|
||||
*/
|
||||
int
|
||||
mdisplacem(magr, mdef, quietly)
|
||||
register struct monst *magr,*mdef;
|
||||
boolean quietly;
|
||||
{
|
||||
struct permonst *pa, *pd;
|
||||
struct monst *mon; /* displaced monster */
|
||||
int tx = mdef->mx, ty = mdef->my; /* destination */
|
||||
int fx = magr->mx, fy = magr->my; /* current location */
|
||||
boolean struck = FALSE;
|
||||
|
||||
pa = magr->data; pd = mdef->data;
|
||||
|
||||
/* The 1 in 7 failure below matches the chance in attack()
|
||||
* for pet displacement.
|
||||
*/
|
||||
if (!rn2(7)) return(MM_MISS);
|
||||
|
||||
/* Grid bugs cannot displace at an angle. */
|
||||
if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
|
||||
&& magr->my != mdef->my)
|
||||
return(MM_MISS);
|
||||
|
||||
|
||||
/* undetected monsters become un-hidden if they are displaced */
|
||||
if (mdef->mundetected)
|
||||
mdef->mundetected = 0;
|
||||
|
||||
/*
|
||||
* Set up the visibility of action.
|
||||
* You can observe monster displacement if you can see both of
|
||||
* the monsters involved.
|
||||
*/
|
||||
vis = (canspotmon(magr) && canspotmon(mdef));
|
||||
|
||||
|
||||
if (touch_petrifies(pd) && !resists_ston(magr)) {
|
||||
if (which_armor(magr, W_ARMG) != 0) {
|
||||
if (poly_when_stoned(pa)) {
|
||||
mon_to_stone(magr);
|
||||
return MM_HIT; /* no damage during the polymorph */
|
||||
}
|
||||
if (!quietly && canspotmon(magr))
|
||||
pline("%s turns to stone!", Monnam(magr));
|
||||
monstone(magr);
|
||||
if (magr->mhp > 0) return 0;
|
||||
else if (magr->mtame && !vis)
|
||||
You(brief_feeling, "peculiarly sad");
|
||||
return MM_AGR_DIED;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_at(fx, fy) == magr)
|
||||
remove_monster(fx, fy); /* pick up from orig position */
|
||||
if ((mon = m_at(tx, ty)) == mdef) {
|
||||
if (!quietly && (vis))
|
||||
pline("%s moves %s out of %s way!",
|
||||
Monnam(magr), mon_nam(mdef),
|
||||
is_rider(pa) ? "the" : mhis(magr));
|
||||
remove_monster(tx, ty);
|
||||
}
|
||||
place_monster(magr,tx,ty); /* put magr down */
|
||||
|
||||
/* Restore original mon */
|
||||
if (mon) {
|
||||
if ((mon->mx != tx) || (mon->my != ty))
|
||||
place_worm_seg(mon, fx, fy);
|
||||
else
|
||||
place_monster(mon, fx, fy);
|
||||
struck = TRUE;
|
||||
} else
|
||||
remove_monster(fx, fy); /* shouldn't happen */
|
||||
newsym(fx,fy); /* see it */
|
||||
newsym(tx,ty); /* all happen */
|
||||
flush_screen(0); /* make sure it shows up */
|
||||
|
||||
/*
|
||||
* Wake up the displaced defender.
|
||||
*/
|
||||
mdef->msleeping = 0;
|
||||
|
||||
return(struck ? MM_HIT : MM_MISS);
|
||||
}
|
||||
#endif /* BARGETHROUGH */
|
||||
|
||||
/*
|
||||
* mattackm() -- a monster attacks another monster.
|
||||
#ifndef BARGETHROUGH
|
||||
*
|
||||
* --------- aggressor died
|
||||
* / ------- defender died
|
||||
* / / ----- defender was hit
|
||||
* / / /
|
||||
* x x x
|
||||
*
|
||||
* 0x4 MM_AGR_DIED
|
||||
* 0x2 MM_DEF_DIED
|
||||
* 0x1 MM_HIT
|
||||
* 0x0 MM_MISS
|
||||
*
|
||||
#endif
|
||||
* Each successive attack has a lower probability of hitting. Some rely on the
|
||||
* success of previous attacks. ** this doen't seem to be implemented -dl **
|
||||
*
|
||||
|
||||
35
src/mon.c
35
src/mon.c
@@ -14,6 +14,9 @@
|
||||
|
||||
STATIC_DCL boolean FDECL(restrap,(struct monst *));
|
||||
STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *));
|
||||
#ifdef BARGETHROUGH
|
||||
STATIC_DCL long FDECL(mm_displacement, (struct monst *,struct monst *));
|
||||
#endif
|
||||
STATIC_DCL int NDECL(pick_animal);
|
||||
STATIC_DCL int FDECL(select_newcham_form, (struct monst *));
|
||||
STATIC_DCL void FDECL(kill_eggs, (struct obj *));
|
||||
@@ -1092,11 +1095,24 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
|
||||
struct monst *mtmp2 = m_at(nx, ny);
|
||||
long mmflag = flag | mm_aggression(mon, mtmp2);
|
||||
|
||||
#ifndef BARGETHROUGH
|
||||
if (!(mmflag & ALLOW_M)) continue;
|
||||
info[cnt] |= ALLOW_M;
|
||||
if (mtmp2->mtame) {
|
||||
if (!(mmflag & ALLOW_TM)) continue;
|
||||
info[cnt] |= ALLOW_TM;
|
||||
#else /* BARGETHROUGH */
|
||||
if (mmflag & ALLOW_M) {
|
||||
info[cnt] |= ALLOW_M;
|
||||
if (mtmp2->mtame) {
|
||||
if (!(mmflag & ALLOW_TM)) continue;
|
||||
info[cnt] |= ALLOW_TM;
|
||||
}
|
||||
} else {
|
||||
mmflag = flag | mm_displacement(mon, mtmp2);
|
||||
if (!(mmflag & ALLOW_MDISP)) continue;
|
||||
info[cnt] |= ALLOW_MDISP;
|
||||
#endif /* BARGETHROUGH */
|
||||
}
|
||||
}
|
||||
/* Note: ALLOW_SANCT only prevents movement, not */
|
||||
@@ -1199,6 +1215,25 @@ struct monst *magr, /* monster that is currently deciding where to move */
|
||||
return 0L;
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
/* Monster displacing another monster out of the way */
|
||||
STATIC_OVL long
|
||||
mm_displacement(magr, mdef)
|
||||
struct monst *magr, /* monster that is currently deciding where to move */
|
||||
*mdef; /* another monster which is next to it */
|
||||
{
|
||||
struct permonst *pa = magr->data;
|
||||
struct permonst *pd = mdef->data;
|
||||
if ((pa->mflags3 & M3_DISPLACES) &&
|
||||
!is_longworm(pd) && /* no displacing longworms */
|
||||
!mdef->mtrapped && /* complex to do right */
|
||||
(is_rider(pa) || /* riders can move anything */
|
||||
pa->msize >= pd->msize)) /* same or smaller only */
|
||||
return ALLOW_MDISP;
|
||||
return 0L;
|
||||
}
|
||||
#endif /* BARGETHROUGH */
|
||||
|
||||
boolean
|
||||
monnear(mon, x, y)
|
||||
register struct monst *mon;
|
||||
|
||||
106
src/monmove.c
106
src/monmove.c
@@ -570,6 +570,52 @@ register struct monst *mtmp;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
/*
|
||||
* should_displace()
|
||||
*
|
||||
* Displacement of another monster is a last resort and only
|
||||
* used on approach. If there are better ways to get to target,
|
||||
* those should be used instead. This function does that evaluation.
|
||||
*/
|
||||
boolean
|
||||
should_displace(mtmp, poss, info, cnt, gx, gy)
|
||||
struct monst *mtmp;
|
||||
coord *poss; /* coord poss[9] */
|
||||
long *info; /* long info[9] */
|
||||
int cnt;
|
||||
xchar gx, gy;
|
||||
{
|
||||
int shortest_with_displacing = -1;
|
||||
int shortest_without_displacing = -1;
|
||||
int count_without_displacing = 0;
|
||||
register int i, nx, ny;
|
||||
int ndist;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
nx = poss[i].x; ny = poss[i].y;
|
||||
ndist = dist2(nx,ny,gx,gy);
|
||||
if (MON_AT(nx,ny) &&
|
||||
(info[i] & ALLOW_MDISP) && !(info[i] & ALLOW_M) &&
|
||||
!undesirable_disp(mtmp,nx,ny)) {
|
||||
if (shortest_with_displacing == -1 ||
|
||||
(ndist < shortest_with_displacing))
|
||||
shortest_with_displacing = ndist;
|
||||
} else {
|
||||
if ((shortest_without_displacing == -1) ||
|
||||
(ndist < shortest_without_displacing))
|
||||
shortest_without_displacing = ndist;
|
||||
count_without_displacing++;
|
||||
}
|
||||
}
|
||||
if (shortest_with_displacing > -1 &&
|
||||
(shortest_with_displacing < shortest_without_displacing ||
|
||||
!count_without_displacing))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* BARGETHROUGH */
|
||||
|
||||
/* Return values:
|
||||
* 0: did not move, but can still attack and do other stuff.
|
||||
* 1: moved, possibly can attack.
|
||||
@@ -589,6 +635,9 @@ register int after;
|
||||
boolean can_open=0, can_unlock=0, doorbuster=0;
|
||||
boolean uses_items=0, setlikes=0;
|
||||
boolean avoid=FALSE;
|
||||
#ifdef BARGETHROUGH
|
||||
boolean better_with_displacing = FALSE;
|
||||
#endif
|
||||
struct permonst *ptr;
|
||||
struct monst *mtoo;
|
||||
schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
|
||||
@@ -909,12 +958,19 @@ not_special:
|
||||
for(i = 0; i < cnt; i++)
|
||||
if(!(info[i] & NOTONL)) avoid=TRUE;
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
better_with_displacing = should_displace(mtmp,poss,info,cnt,gx,gy);
|
||||
#endif
|
||||
for(i=0; i < cnt; i++) {
|
||||
if (avoid && (info[i] & NOTONL)) continue;
|
||||
nx = poss[i].x;
|
||||
ny = poss[i].y;
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
if (MON_AT(nx,ny) &&
|
||||
(info[i] & ALLOW_MDISP) && !(info[i] & ALLOW_M) &&
|
||||
!better_with_displacing) continue;
|
||||
#endif
|
||||
if (appr != 0) {
|
||||
mtrk = &mtmp->mtrack[0];
|
||||
for(j=0; j < jcnt; mtrk++, j++)
|
||||
@@ -1010,6 +1066,19 @@ not_special:
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
if((info[chi] & ALLOW_MDISP)) {
|
||||
struct monst *mtmp2;
|
||||
int mstatus;
|
||||
mtmp2 = m_at(nix,niy);
|
||||
mstatus = mdisplacem(mtmp, mtmp2, FALSE);
|
||||
if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED))
|
||||
return 2;
|
||||
if (mstatus & MM_HIT) return 1;
|
||||
return 3;
|
||||
}
|
||||
#endif /* BARGETHROUGH */
|
||||
|
||||
if (!m_in_out_region(mtmp,nix,niy))
|
||||
return 3;
|
||||
remove_monster(omx, omy);
|
||||
@@ -1287,6 +1356,41 @@ found_you:
|
||||
mtmp->muy = my;
|
||||
}
|
||||
|
||||
#ifdef BARGETHROUGH
|
||||
/*
|
||||
* mon-to-mon displacement is a deliberate "get out of my way" act,
|
||||
* not an accidental bump, so we don't consider mstun or mconf in
|
||||
* undesired_disp().
|
||||
*
|
||||
* We do consider many other things about the target and its
|
||||
* location however.
|
||||
*/
|
||||
boolean
|
||||
undesirable_disp(mtmp, x, y)
|
||||
struct monst *mtmp;
|
||||
xchar x,y;
|
||||
{
|
||||
struct permonst *mdat = mtmp->data;
|
||||
boolean is_pet = (mtmp && mtmp->mtame && !mtmp->isminion);
|
||||
struct trap *trap = t_at(x,y);
|
||||
|
||||
if (is_pet) {
|
||||
/* Pets avoid a trap if you've seen it usually. */
|
||||
if (trap && trap->tseen && rn2(40))
|
||||
return TRUE;
|
||||
/* Pets avoid cursed locations */
|
||||
if (cursed_object_at(x,y))
|
||||
return TRUE;
|
||||
}
|
||||
/* Monsters avoid a trap if they've seen that type before */
|
||||
else if (trap && rn2(40) &&
|
||||
(mtmp->mtrapseen & (1 << (trap->ttyp -1))) != 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* BARGETHROUGH */
|
||||
|
||||
boolean
|
||||
can_ooze(mtmp)
|
||||
struct monst *mtmp;
|
||||
|
||||
@@ -2748,7 +2748,7 @@ struct permonst _mons2[] = {
|
||||
MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0,
|
||||
M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL,
|
||||
M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY,
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD),
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION|M3_DISPLACES, HI_LORD),
|
||||
MON("Pestilence", S_DEMON,
|
||||
LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN),
|
||||
A(ATTK(AT_TUCH, AD_PEST, 8, 8), ATTK(AT_TUCH, AD_PEST, 8, 8),
|
||||
@@ -2757,7 +2757,7 @@ struct permonst _mons2[] = {
|
||||
MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0,
|
||||
M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL,
|
||||
M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY,
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD),
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION|M3_DISPLACES, HI_LORD),
|
||||
MON("Famine", S_DEMON,
|
||||
LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN),
|
||||
A(ATTK(AT_TUCH, AD_FAMN, 8, 8), ATTK(AT_TUCH, AD_FAMN, 8, 8),
|
||||
@@ -2766,7 +2766,7 @@ struct permonst _mons2[] = {
|
||||
MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0,
|
||||
M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL,
|
||||
M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY,
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD),
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION|M3_DISPLACES, HI_LORD),
|
||||
/* other demons
|
||||
*/
|
||||
#ifdef MAIL
|
||||
|
||||
@@ -416,6 +416,9 @@ tele()
|
||||
|
||||
if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
|
||||
You_feel("disoriented for a moment.");
|
||||
#ifdef WIZARD
|
||||
if (wizard && yn("Override?") != 'y')
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if ((Teleport_control && !Stunned)
|
||||
|
||||
@@ -676,6 +676,9 @@ static const char *build_opts[] = {
|
||||
#ifdef MAIL
|
||||
"mail daemon",
|
||||
#endif
|
||||
#ifdef BARGETHROUGH
|
||||
"monsters moving monsters",
|
||||
#endif
|
||||
#ifdef GNUDOS
|
||||
"MSDOS protected mode",
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user