breath attack directed at self by poly'd hero always hits
override non-silver vs shades for artifacts which deal extra damage to undead
assorted mirror fixes--mainly visibility issues
+some monsters can't be strangled; self-polymorph can stop/restart strangulation
Platform- and/or Interface-Specific Fixes
E boolean FDECL(mon_hates_silver, (struct monst *));
E boolean FDECL(passes_bars, (struct permonst *));
E boolean FDECL(can_blow, (struct monst *));
+E boolean FDECL(can_be_strangled, (struct monst *));
E boolean FDECL(can_track, (struct permonst *));
E boolean FDECL(breakarm, (struct permonst *));
E boolean FDECL(sliparm, (struct permonst *));
-/* SCCS Id: @(#)do_wear.c 3.5 2007/03/19 */
+/* SCCS Id: @(#)do_wear.c 3.5 2007/05/16 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
break;
}
case AMULET_OF_STRANGULATION:
- makeknown(AMULET_OF_STRANGULATION);
- pline("It constricts your throat!");
- Strangled = 6;
+ if (can_be_strangled(&youmonst)) {
+ makeknown(AMULET_OF_STRANGULATION);
+ pline("It constricts your throat!");
+ Strangled = 6L;
+ }
break;
case AMULET_OF_RESTFUL_SLEEP:
HSleeping = rnd(100);
break;
case AMULET_OF_STRANGULATION:
if (Strangled) {
+ if (Breathless)
+ Your("%s is no longer constricted!", body_part(NECK));
+ else
You("can breathe more easily!");
- Strangled = 0;
+ Strangled = 0L;
}
break;
case AMULET_OF_RESTFUL_SLEEP:
-/* SCCS Id: @(#)mondata.c 3.5 2007/03/02 */
+/* SCCS Id: @(#)mondata.c 3.5 2007/05/16 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
return TRUE;
}
+boolean
+can_be_strangled(mon) /* TRUE if mon is vulnerable to strangulation */
+struct monst *mon;
+{
+ struct obj *mamul;
+ boolean nonbreathing, nobrainer;
+
+ /* For amulet of strangulation support: here we're considering
+ strangulation to be loss of blood flow to the brain due to
+ constriction of the arteries in the neck, so all headless
+ creatures are immune (no neck) as are mindless creatures
+ who don't need to breathe (brain, if any, doesn't care).
+ Mindless creatures who do need to breath are vulnerable, as
+ are non-breathing creatures which have higher brain function. */
+ if (!has_head(mon->data)) return FALSE;
+ if (mon == &youmonst) {
+ /* hero can't be mindless but poly'ing into mindless form can
+ confer strangulation protection */
+ nobrainer = mindless(youmonst.data);
+ nonbreathing = Breathless;
+ } else {
+ nobrainer = mindless(mon->data);
+ /* monsters don't wear amulets of magical breathing,
+ so second part doesn't achieve anything useful... */
+ nonbreathing = (breathless(mon->data) ||
+ ((mamul = which_armor(mon, W_AMUL)) != 0 &&
+ (mamul->otyp == AMULET_OF_MAGICAL_BREATHING)));
+ }
+ return (boolean)(!nobrainer || !nonbreathing);
+}
+
boolean
can_track(ptr) /* returns TRUE if monster can track well */
register struct permonst *ptr;
#include "hack.h"
+STATIC_DCL void FDECL(check_strangling, (BOOLEAN_P));
STATIC_DCL void FDECL(polyman, (const char *,const char *));
STATIC_DCL void NDECL(break_armor);
STATIC_DCL void FDECL(drop_weapon,(int));
#endif
}
+/* for changing into form that's immune to strangulation */
+STATIC_OVL void
+check_strangling(on)
+boolean on;
+{
+ if (on) { /* on -- maybe resume strangling */
+ /* when Strangled is already set, polymorphing from one
+ vulnerable form into another causes the counter to be reset */
+ if (uamul && uamul->otyp == AMULET_OF_STRANGULATION &&
+ can_be_strangled(&youmonst)) {
+ Your("%s %s your %s!", simpleonames(uamul),
+ Strangled ? "still constricts" : "begins constricting",
+ body_part(NECK)); /* "throat" */
+ Strangled = 6L;
+ makeknown(AMULET_OF_STRANGULATION);
+ }
+ } else { /* off -- maybe block strangling */
+ if (Strangled && !can_be_strangled(&youmonst)) {
+ Strangled = 0L;
+ You("are no longer being strangled.");
+ }
+ }
+}
+
/* make a (new) human out of the player */
STATIC_OVL void
polyman(fmt, arg)
Blinded = 1L;
make_blinded(0L, TRUE); /* remove blindness */
}
+ check_strangling(TRUE);
if(!Levitation && !u.ustuck &&
(is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy)))
make_slimed(0L, (char*) 0);
}
}
+ check_strangling(FALSE); /* maybe stop strangling */
if (nohands(youmonst.data)) Glib = 0;
/*
You("orient yourself on the web.");
u.utrap = 0;
}
+ check_strangling(TRUE); /* maybe start strangling */
(void) polysense(youmonst.data);
context.botl = 1;
Strcpy(killer.name,
(u.uburied) ? "suffocation" : "strangulation");
done(DIED);
+ /* must be declining to die in explore|wizard mode;
+ treat like being cured of strangulation by prayer */
+ if (uamul && uamul->otyp == AMULET_OF_STRANGULATION) {
+ Your("amulet vanishes!");
+ useup(uamul);
+ }
break;
case FUMBLING:
/* call this only when a move took place. */