From fa1f1134c8c06567522f6db3843e067921cbf79c Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Mon, 25 Sep 2023 16:45:32 -0400 Subject: [PATCH] Disambiguate b_trapped null bodypart value b_trapped was treating 0 as a null value for its bodypart parameter, but 0 is actually the value of ARM, so b_trapped(..., ARM) would be treated as intending no A_CON abuse. Add NO_PART = -1 to the bodypart_types enum, and use that instead of 0 as the "no body part" value in b_trapped, so that ARM can be passed to it without any ambiguity. aosdict identified this issue in xNetHack and handled it differently; he added NO_PART with a value of 0, incremented the existing bodypart_types values, and padded the body part arrays so the actual body parts would start at index 1. I think using NO_PART = -1 is simpler, but that's an alternative approach that can be used instead -- it is advantageous in that it automatically fixes any other places where 0 is assumed to be a non-body-part value that I may have overlooked. --- include/hack.h | 1 + src/detect.c | 2 +- src/dig.c | 2 +- src/eat.c | 2 +- src/hack.c | 4 ++-- src/polyself.c | 5 +++++ src/trap.c | 2 +- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/hack.h b/include/hack.h index 9a5e1f7bb..edb654a2c 100644 --- a/include/hack.h +++ b/include/hack.h @@ -132,6 +132,7 @@ enum bhit_call_types { /* Macros for messages referring to hands, eyes, feet, etc... */ enum bodypart_types { + NO_PART = -1, ARM = 0, EYE = 1, FACE = 2, diff --git a/src/detect.c b/src/detect.c index 793b9b92e..b983c8f17 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1640,7 +1640,7 @@ openone(coordxy zx, coordxy zy, genericptr_t num) cvt_sdoor_to_door(&levl[zx][zy]); /* .typ = DOOR */ if (levl[zx][zy].doormask & D_TRAPPED) { if (distu(zx, zy) < 3) - b_trapped("door", 0); + b_trapped("door", NO_PART); else Norep("You %s an explosion!", cansee(zx, zy) ? "see" : (!Deaf ? "hear" diff --git a/src/dig.c b/src/dig.c index 93c64c5bf..8c4e2f269 100644 --- a/src/dig.c +++ b/src/dig.c @@ -454,7 +454,7 @@ dig(void) } if (IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) { lev->doormask = D_NODOOR; - b_trapped("door", 0); + b_trapped("door", NO_PART); newsym(dpx, dpy); } cleanup: diff --git a/src/eat.c b/src/eat.c index edff2221b..a3d918de5 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1465,7 +1465,7 @@ consume_tin(const char *mesg) r = tin_variety(tin, FALSE); if (tin->otrapped || (tin->cursed && r != HOMEMADE_TIN && !rn2(8))) { - b_trapped("tin", 0); + b_trapped("tin", NO_PART); tin = costly_tin(COST_DSTROY); goto use_up_tin; } diff --git a/src/hack.c b/src/hack.c index ac3798472..deaa1be63 100644 --- a/src/hack.c +++ b/src/hack.c @@ -693,7 +693,7 @@ still_chewing(coordxy x, coordxy y) } else if (lev->typ == SDOOR) { if (lev->doormask & D_TRAPPED) { lev->doormask = D_NODOOR; - b_trapped("secret door", 0); + b_trapped("secret door", NO_PART); } else { digtxt = "chew through the secret door."; lev->doormask = D_BROKEN; @@ -707,7 +707,7 @@ still_chewing(coordxy x, coordxy y) } if (lev->doormask & D_TRAPPED) { lev->doormask = D_NODOOR; - b_trapped("door", 0); + b_trapped("door", NO_PART); } else { digtxt = "chew through the door."; lev->doormask = D_BROKEN; diff --git a/src/polyself.c b/src/polyself.c index b732527ac..902fec1b5 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1988,6 +1988,11 @@ mbodypart(struct monst *mon, int part) }; struct permonst *mptr = mon->data; + if (part <= NO_PART) { + impossible("mbodypart: bad part %d", part); + return "mystery part"; + } + /* some special cases */ if (mptr->mlet == S_DOG || mptr->mlet == S_FELINE || mptr->mlet == S_RODENT || mptr == &mons[PM_OWLBEAR]) { diff --git a/src/trap.c b/src/trap.c index 2db4de9bd..621d7bc4c 100644 --- a/src/trap.c +++ b/src/trap.c @@ -6265,7 +6265,7 @@ b_trapped(const char* item, int bodypart) wake_nearby(); losehp(Maybe_Half_Phys(dmg), "explosion", KILLED_BY_AN); exercise(A_STR, FALSE); - if (bodypart) + if (bodypart != NO_PART) exercise(A_CON, FALSE); make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE); }