hats vs horns
Some recent newsgroup discussion claiming that a pet ki-rin was wearing a helmet (I think poster was hallucinating) caused me to look at some of the hat handling code. There were a couple of noticeable problems and one latent one in code added for 3.4.1. Polymorphing into a minotaur pushes hard helmets off hero's head, but nothing prevented you from putting one right back on. Helmet wearing monsters who polymorphed into minotaurs weren't affected at all. And message handling always assumed multiple horns even though we have some singled horned monsters, but since all those have no hands they can't wear any armor and that potential pluralization issue wasn't noticeable.
This commit is contained in:
@@ -1154,6 +1154,7 @@ E boolean FDECL(can_track, (struct permonst *));
|
|||||||
E boolean FDECL(breakarm, (struct permonst *));
|
E boolean FDECL(breakarm, (struct permonst *));
|
||||||
E boolean FDECL(sliparm, (struct permonst *));
|
E boolean FDECL(sliparm, (struct permonst *));
|
||||||
E boolean FDECL(sticks, (struct permonst *));
|
E boolean FDECL(sticks, (struct permonst *));
|
||||||
|
E int FDECL(num_horns, (struct permonst *));
|
||||||
/* E boolean FDECL(canseemon, (struct monst *)); */
|
/* E boolean FDECL(canseemon, (struct monst *)); */
|
||||||
E struct attack *FDECL(dmgtype_fromattack, (struct permonst *,int,int));
|
E struct attack *FDECL(dmgtype_fromattack, (struct permonst *,int,int));
|
||||||
E boolean FDECL(dmgtype, (struct permonst *,int));
|
E boolean FDECL(dmgtype, (struct permonst *,int));
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
/* SCCS Id: @(#)mondata.h 3.4 2001/02/14 */
|
/* SCCS Id: @(#)mondata.h 3.4 2003/01/08 */
|
||||||
/* Copyright (c) 1989 Mike Threepoint */
|
/* Copyright (c) 1989 Mike Threepoint */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
#define nolimbs(ptr) (((ptr)->mflags1 & M1_NOLIMBS) == M1_NOLIMBS)
|
#define nolimbs(ptr) (((ptr)->mflags1 & M1_NOLIMBS) == M1_NOLIMBS)
|
||||||
#define notake(ptr) (((ptr)->mflags1 & M1_NOTAKE) != 0L)
|
#define notake(ptr) (((ptr)->mflags1 & M1_NOTAKE) != 0L)
|
||||||
#define has_head(ptr) (((ptr)->mflags1 & M1_NOHEAD) == 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 || \
|
#define is_whirly(ptr) ((ptr)->mlet == S_VORTEX || \
|
||||||
(ptr) == &mons[PM_AIR_ELEMENTAL])
|
(ptr) == &mons[PM_AIR_ELEMENTAL])
|
||||||
#define is_silent(ptr) ((ptr)->msound == MS_SILENT)
|
#define is_silent(ptr) ((ptr)->msound == MS_SILENT)
|
||||||
|
|||||||
+7
-1
@@ -1,4 +1,4 @@
|
|||||||
/* 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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -1202,6 +1202,12 @@ boolean noisy;
|
|||||||
if (uarmh) {
|
if (uarmh) {
|
||||||
if (noisy) already_wearing(an(c_helmet));
|
if (noisy) already_wearing(an(c_helmet));
|
||||||
err++;
|
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
|
} else
|
||||||
*mask = W_ARMH;
|
*mask = W_ARMH;
|
||||||
} else if (is_shield(otmp)) {
|
} else if (is_shield(otmp)) {
|
||||||
|
|||||||
+22
-2
@@ -1,4 +1,4 @@
|
|||||||
/* 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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -301,6 +301,26 @@ sticks(ptr) /* creature sticks other creatures it hits */
|
|||||||
attacktype(ptr,AT_HUGS)));
|
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 *
|
struct attack *
|
||||||
dmgtype_fromattack(ptr, dtyp, atyp)
|
dmgtype_fromattack(ptr, dtyp, atyp)
|
||||||
struct permonst *ptr;
|
struct permonst *ptr;
|
||||||
@@ -365,7 +385,7 @@ monsndx(ptr) /* return an index into the mons array */
|
|||||||
/* ought to switch this to use `fmt_ptr' */
|
/* ought to switch this to use `fmt_ptr' */
|
||||||
panic("monsndx - could not index monster (%lx)",
|
panic("monsndx - could not index monster (%lx)",
|
||||||
(unsigned long)ptr);
|
(unsigned long)ptr);
|
||||||
return FALSE; /* will not get here */
|
return NON_PM; /* will not get here */
|
||||||
}
|
}
|
||||||
|
|
||||||
return(i);
|
return(i);
|
||||||
|
|||||||
+15
-13
@@ -1,4 +1,4 @@
|
|||||||
/* 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 */
|
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -617,18 +617,20 @@ break_armor()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (has_horns(youmonst.data)) {
|
if (has_horns(youmonst.data)) {
|
||||||
if ((otmp = uarmh) != 0) {
|
if ((otmp = uarmh) != 0) {
|
||||||
if (is_flimsy(otmp) && !donning(otmp)) {
|
if (is_flimsy(otmp) && !donning(otmp)) {
|
||||||
char yourbuf[BUFSZ];
|
char hornbuf[BUFSZ], yourbuf[BUFSZ];
|
||||||
/* Future possiblities: This could damage/destroy helmet*/
|
|
||||||
Your("horns pierce through %s %s.", shk_your(yourbuf, otmp),
|
/* Future possiblities: This could damage/destroy helmet */
|
||||||
xname(otmp));
|
Sprintf(hornbuf, "horn%s", plur(num_horns(youmonst.data)));
|
||||||
} else {
|
Your("%s %s through %s %s.", vtense(hornbuf, "pierce"),
|
||||||
if (donning(otmp)) cancel_don();
|
shk_your(yourbuf, otmp), xname(otmp));
|
||||||
Your("helmet falls to the %s!", surface(u.ux, u.uy));
|
} else {
|
||||||
(void) Helmet_off();
|
if (donning(otmp)) cancel_don();
|
||||||
dropx(otmp);
|
Your("helmet falls to the %s!", surface(u.ux, u.uy));
|
||||||
}
|
(void) Helmet_off();
|
||||||
|
dropx(otmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nohands(youmonst.data) || verysmall(youmonst.data)) {
|
if (nohands(youmonst.data) || verysmall(youmonst.data)) {
|
||||||
|
|||||||
+11
-5
@@ -1,4 +1,4 @@
|
|||||||
/* 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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -436,6 +436,8 @@ boolean racialexception;
|
|||||||
break;
|
break;
|
||||||
case W_ARMH:
|
case W_ARMH:
|
||||||
if (!is_helmet(obj)) continue;
|
if (!is_helmet(obj)) continue;
|
||||||
|
/* (flimsy exception matches polyself handling) */
|
||||||
|
if (has_horns(mon->data) && !is_flimsy(obj)) continue;
|
||||||
break;
|
break;
|
||||||
case W_ARMS:
|
case W_ARMS:
|
||||||
if (!is_shield(obj)) continue;
|
if (!is_shield(obj)) continue;
|
||||||
@@ -596,6 +598,7 @@ boolean polyspot;
|
|||||||
register struct obj *otmp;
|
register struct obj *otmp;
|
||||||
struct permonst *mdat = mon->data;
|
struct permonst *mdat = mon->data;
|
||||||
boolean vis = cansee(mon->mx, mon->my);
|
boolean vis = cansee(mon->mx, mon->my);
|
||||||
|
boolean handless_or_tiny = (nohands(mdat) || verysmall(mdat));
|
||||||
const char *pronoun = mhim(mon),
|
const char *pronoun = mhim(mon),
|
||||||
*ppronoun = mhis(mon);
|
*ppronoun = mhis(mon);
|
||||||
|
|
||||||
@@ -675,7 +678,7 @@ boolean polyspot;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (nohands(mdat) || verysmall(mdat)) {
|
if (handless_or_tiny) {
|
||||||
/* [caller needs to handle weapon checks] */
|
/* [caller needs to handle weapon checks] */
|
||||||
if ((otmp = which_armor(mon, W_ARMG)) != 0) {
|
if ((otmp = which_armor(mon, W_ARMG)) != 0) {
|
||||||
if (vis)
|
if (vis)
|
||||||
@@ -693,7 +696,11 @@ boolean polyspot;
|
|||||||
if (polyspot) bypass_obj(otmp);
|
if (polyspot) bypass_obj(otmp);
|
||||||
m_lose_armor(mon, 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)
|
if (vis)
|
||||||
pline("%s helmet falls to the %s!",
|
pline("%s helmet falls to the %s!",
|
||||||
s_suffix(Monnam(mon)), surface(mon->mx, mon->my));
|
s_suffix(Monnam(mon)), surface(mon->mx, mon->my));
|
||||||
@@ -703,8 +710,7 @@ boolean polyspot;
|
|||||||
m_lose_armor(mon, otmp);
|
m_lose_armor(mon, otmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nohands(mdat) || verysmall(mdat) || slithy(mdat) ||
|
if (handless_or_tiny || slithy(mdat) || mdat->mlet == S_CENTAUR) {
|
||||||
mdat->mlet == S_CENTAUR) {
|
|
||||||
if ((otmp = which_armor(mon, W_ARMF)) != 0) {
|
if ((otmp = which_armor(mon, W_ARMF)) != 0) {
|
||||||
if (vis) {
|
if (vis) {
|
||||||
if (is_whirly(mon->data))
|
if (is_whirly(mon->data))
|
||||||
|
|||||||
Reference in New Issue
Block a user