E boolean FDECL(breakarm, (struct permonst *));
E boolean FDECL(sliparm, (struct permonst *));
E boolean FDECL(sticks, (struct permonst *));
+E int FDECL(num_horns, (struct permonst *));
/* E boolean FDECL(canseemon, (struct monst *)); */
E struct attack *FDECL(dmgtype_fromattack, (struct permonst *,int,int));
E boolean FDECL(dmgtype, (struct permonst *,int));
-/* SCCS Id: @(#)mondata.h 3.4 2001/02/14 */
+/* SCCS Id: @(#)mondata.h 3.4 2003/01/08 */
/* Copyright (c) 1989 Mike Threepoint */
/* NetHack may be freely redistributed. See license for details. */
#define nolimbs(ptr) (((ptr)->mflags1 & M1_NOLIMBS) == M1_NOLIMBS)
#define notake(ptr) (((ptr)->mflags1 & M1_NOTAKE) != 0L)
#define has_head(ptr) (((ptr)->mflags1 & M1_NOHEAD) == 0L)
-#define has_horns(ptr) ((ptr) == &mons[PM_MINOTAUR])
+#define has_horns(ptr) (num_horns(ptr) > 0)
#define is_whirly(ptr) ((ptr)->mlet == S_VORTEX || \
(ptr) == &mons[PM_AIR_ELEMENTAL])
#define is_silent(ptr) ((ptr)->msound == MS_SILENT)
-/* SCCS Id: @(#)do_wear.c 3.4 2002/11/29 */
+/* SCCS Id: @(#)do_wear.c 3.4 2003/01/08 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
if (uarmh) {
if (noisy) already_wearing(an(c_helmet));
err++;
+ } else if (Upolyd && has_horns(youmonst.data) && !is_flimsy(otmp)) {
+ /* (flimsy exception matches polyself handling) */
+ if (noisy)
+ pline_The("%s won't fit over your horn%s.",
+ c_helmet, plur(num_horns(youmonst.data)));
+ err++;
} else
*mask = W_ARMH;
} else if (is_shield(otmp)) {
-/* SCCS Id: @(#)mondata.c 3.4 2002/12/09 */
+/* SCCS Id: @(#)mondata.c 3.4 2003/01/08 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
attacktype(ptr,AT_HUGS)));
}
+/* number of horns this type of monster has on its head */
+int
+num_horns(ptr)
+struct permonst *ptr;
+{
+ switch (monsndx(ptr)) {
+ case PM_HORNED_DEVIL: /* ? "more than one" */
+ case PM_MINOTAUR:
+ return 2;
+ case PM_WHITE_UNICORN:
+ case PM_GRAY_UNICORN:
+ case PM_BLACK_UNICORN:
+ case PM_KI_RIN:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
struct attack *
dmgtype_fromattack(ptr, dtyp, atyp)
struct permonst *ptr;
/* ought to switch this to use `fmt_ptr' */
panic("monsndx - could not index monster (%lx)",
(unsigned long)ptr);
- return FALSE; /* will not get here */
+ return NON_PM; /* will not get here */
}
return(i);
-/* SCCS Id: @(#)polyself.c 3.4 2002/07/11 */
+/* SCCS Id: @(#)polyself.c 3.4 2003/01/08 */
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
#endif
}
if (has_horns(youmonst.data)) {
- if ((otmp = uarmh) != 0) {
- if (is_flimsy(otmp) && !donning(otmp)) {
- char yourbuf[BUFSZ];
- /* Future possiblities: This could damage/destroy helmet*/
- Your("horns pierce through %s %s.", shk_your(yourbuf, otmp),
- xname(otmp));
- } else {
- if (donning(otmp)) cancel_don();
- Your("helmet falls to the %s!", surface(u.ux, u.uy));
- (void) Helmet_off();
- dropx(otmp);
- }
+ if ((otmp = uarmh) != 0) {
+ if (is_flimsy(otmp) && !donning(otmp)) {
+ char hornbuf[BUFSZ], yourbuf[BUFSZ];
+
+ /* Future possiblities: This could damage/destroy helmet */
+ Sprintf(hornbuf, "horn%s", plur(num_horns(youmonst.data)));
+ Your("%s %s through %s %s.", vtense(hornbuf, "pierce"),
+ shk_your(yourbuf, otmp), xname(otmp));
+ } else {
+ if (donning(otmp)) cancel_don();
+ Your("helmet falls to the %s!", surface(u.ux, u.uy));
+ (void) Helmet_off();
+ dropx(otmp);
+ }
}
}
if (nohands(youmonst.data) || verysmall(youmonst.data)) {
-/* SCCS Id: @(#)worn.c 3.4 2002/11/07 */
+/* SCCS Id: @(#)worn.c 3.4 2003/01/08 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
break;
case W_ARMH:
if (!is_helmet(obj)) continue;
+ /* (flimsy exception matches polyself handling) */
+ if (has_horns(mon->data) && !is_flimsy(obj)) continue;
break;
case W_ARMS:
if (!is_shield(obj)) continue;
register struct obj *otmp;
struct permonst *mdat = mon->data;
boolean vis = cansee(mon->mx, mon->my);
+ boolean handless_or_tiny = (nohands(mdat) || verysmall(mdat));
const char *pronoun = mhim(mon),
*ppronoun = mhis(mon);
}
#endif
}
- if (nohands(mdat) || verysmall(mdat)) {
+ if (handless_or_tiny) {
/* [caller needs to handle weapon checks] */
if ((otmp = which_armor(mon, W_ARMG)) != 0) {
if (vis)
if (polyspot) bypass_obj(otmp);
m_lose_armor(mon, otmp);
}
- if ((otmp = which_armor(mon, W_ARMH)) != 0) {
+ }
+ if (handless_or_tiny || has_horns(mdat)) {
+ if ((otmp = which_armor(mon, W_ARMH)) != 0 &&
+ /* flimsy test for horns matches polyself handling */
+ (handless_or_tiny || !is_flimsy(otmp))) {
if (vis)
pline("%s helmet falls to the %s!",
s_suffix(Monnam(mon)), surface(mon->mx, mon->my));
m_lose_armor(mon, otmp);
}
}
- if (nohands(mdat) || verysmall(mdat) || slithy(mdat) ||
- mdat->mlet == S_CENTAUR) {
+ if (handless_or_tiny || slithy(mdat) || mdat->mlet == S_CENTAUR) {
if ((otmp = which_armor(mon, W_ARMF)) != 0) {
if (vis) {
if (is_whirly(mon->data))