From c4c1b064f75e30b2cc3b96cbfeeb45e81b42d33e Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Wed, 14 May 2003 10:25:26 +0000 Subject: [PATCH] fix B02004 and other projectile related killer reasons 1) killer reason for scattered land mine shrapnel used "a" or "an" prefix even when multiple projectiles hit as a group -- one of various things From a bug report.oextra field) -- noticed while investigating #1 and later From a bug report.4.0 due to an unintentional side-effect of missile killer reason handling in 3.4.1 (removal of redundant "poisoned" prefix by m_throw() confused the poison handling routine) -- noticed while investigating #3. --- doc/fixes34.2 | 6 ++++++ include/extern.h | 1 + src/mon.c | 23 +++++++++++++---------- src/mthrowu.c | 43 +++++++++++-------------------------------- src/objnam.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/trap.c | 4 ++-- 6 files changed, 75 insertions(+), 45 deletions(-) diff --git a/doc/fixes34.2 b/doc/fixes34.2 index 78a4ad1dd..1bc43f460 100644 --- a/doc/fixes34.2 +++ b/doc/fixes34.2 @@ -59,6 +59,12 @@ when polymorhed, only hand/weapon attack on disenchanter should result in damage to weapon, gloves, etc. killer should say "the" when choking on unique monster's corpse allow applying polearm on monster you can see via infravision +killer reason shouldn't use "a" or "an" prefix for multiple projectiles + scattered by land mine explosion +killer reason for named missile could end up with garbage instead of the name +make killer reason for various poisioning deaths be more consistent +poison missiles were unintentionally more likely to inflict "deadly poison" + than in pre-3.4.1 releases Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index abfe6be65..2356a1950 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1352,6 +1352,7 @@ E char *FDECL(doname, (struct obj *)); E boolean FDECL(not_fully_identified, (struct obj *)); E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P)); E char *FDECL(cxname, (struct obj *)); +E char *FDECL(killer_xname, (struct obj *)); E const char *FDECL(singular, (struct obj *,char *(*)(OBJ_P))); E char *FDECL(an, (const char *)); E char *FDECL(An, (const char *)); diff --git a/src/mon.c b/src/mon.c index 72c81f8e4..d49b801da 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mon.c 3.4 2003/01/29 */ +/* SCCS Id: @(#)mon.c 3.4 2003/05/09 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1958,13 +1958,13 @@ poisontell(typ) void poisoned(string, typ, pname, fatal) -register const char *string, *pname; -register int typ, fatal; +const char *string, *pname; +int typ, fatal; { - register int i, plural; - boolean thrown_weapon = !strncmp(string, "poison", 6); - /* admittedly a kludge... */ + int i, plural, kprefix = KILLED_BY_AN; + boolean thrown_weapon = (fatal < 0); + if (thrown_weapon) fatal = -fatal; if(strcmp(string, "blast") && !thrown_weapon) { /* 'blast' has already given a 'poison gas' message */ /* so have "poison arrow", "poison dart", etc... */ @@ -1979,6 +1979,9 @@ register int typ, fatal; pline_The("poison doesn't seem to affect you."); return; } + if (!strncmpi(pname, "the ", 4) || + !strncmpi(pname, "an ", 3) || + !strncmpi(pname, "a ", 2)) kprefix = KILLED_BY_AN; i = rn2(fatal + 20*thrown_weapon); if(i == 0 && typ != A_CHA) { u.uhp = -1; @@ -1986,17 +1989,17 @@ register int typ, fatal; } else if(i <= 5) { /* Check that a stat change was made */ if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1)) - pline("You%s!", poiseff[typ]); + pline("You%s!", poiseff[typ]); } else { i = thrown_weapon ? rnd(6) : rn1(10,6); if(Half_physical_damage) i = (i+1) / 2; - losehp(i, pname, KILLED_BY_AN); + losehp(i, pname, kprefix); } if(u.uhp < 1) { - killer_format = KILLED_BY_AN; + killer_format = kprefix; killer = pname; /* "Poisoned by a poisoned ___" is redundant */ - done(thrown_weapon ? DIED : POISONING); + done(strstri(pname, "poison") ? DIED : POISONING); } (void) encumber_msg(); } diff --git a/src/mthrowu.c b/src/mthrowu.c index e368b0994..3038ced80 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)mthrowu.c 3.4 2002/11/07 */ +/* SCCS Id: @(#)mthrowu.c 3.4 2003/05/09 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -41,30 +41,21 @@ const char *name; /* if null, then format `obj' */ { const char *onm, *knm; boolean is_acid; + int kprefix = KILLED_BY_AN; char onmbuf[BUFSZ], knmbuf[BUFSZ]; if (!name) { - struct obj otmp; - unsigned save_ocknown; - if (!obj) panic("thitu: name & obj both null?"); name = strcpy(onmbuf, (obj->quan > 1L) ? doname(obj) : mshot_xname(obj)); - /* killer name should be more specific; however, exact info - like blessed/cursed and rustproof make things too verbose */ - otmp = *obj; - save_ocknown = objects[otmp.otyp].oc_name_known; - otmp.known = otmp.dknown = 1; - otmp.bknown = otmp.rknown = otmp.greased = 0; - /* "killed by poisoned " would be misleading - since poison is not the cause of death */ - otmp.opoisoned = 0; - objects[otmp.otyp].oc_name_known = 1; - knm = strcpy(knmbuf, - (otmp.quan > 1L) ? doname(&otmp) : xname(&otmp)); - objects[otmp.otyp].oc_name_known = save_ocknown; + knm = strcpy(knmbuf, killer_xname(obj)); + kprefix = KILLED_BY; /* killer_name supplies "an" if warranted */ } else { knm = name; + /* [perhaps ought to check for plural here to] */ + if (!strncmpi(name, "the ", 4) || + !strncmpi(name, "an ", 3) || + !strncmpi(name, "a ", 2)) kprefix = KILLED_BY; } onm = (obj && obj_is_pname(obj)) ? the(name) : (obj && obj->quan > 1L) ? name : an(name); @@ -89,8 +80,7 @@ const char *name; /* if null, then format `obj' */ else { if (is_acid) pline("It burns!"); if (Half_physical_damage) dam = (dam+1) / 2; - losehp(dam, knm, (obj && obj_is_pname(obj)) ? - KILLED_BY : KILLED_BY_AN); + losehp(dam, knm, kprefix); exercise(A_STR, FALSE); } return(1); @@ -393,21 +383,10 @@ m_throw(mon, x, y, dx, dy, range, obj) if (hitu && singleobj->opoisoned && is_poisonable(singleobj)) { char onmbuf[BUFSZ], knmbuf[BUFSZ]; - struct obj otmp; - unsigned save_ocknown; - /* [see thitu()'s handling of `name'] */ Strcpy(onmbuf, xname(singleobj)); - otmp = *singleobj; - save_ocknown = objects[otmp.otyp].oc_name_known; - otmp.known = otmp.dknown = 1; - otmp.bknown = otmp.rknown = otmp.greased = 0; - /* "poisoned by poisoned " would be redundant */ - otmp.opoisoned = 0; - objects[otmp.otyp].oc_name_known = 1; - Strcpy(knmbuf, xname(&otmp)); - poisoned(onmbuf, A_STR, knmbuf, 10); - objects[otmp.otyp].oc_name_known = save_ocknown; + Strcpy(knmbuf, killer_xname(singleobj)); + poisoned(onmbuf, A_STR, knmbuf, -10); } if(hitu && can_blnd((struct monst*)0, &youmonst, diff --git a/src/objnam.c b/src/objnam.c index bd9e0a6fc..472223f91 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)objnam.c 3.4 2003/03/30 */ +/* SCCS Id: @(#)objnam.c 3.4 2003/05/09 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -854,6 +854,47 @@ struct obj *obj; return xname(obj); } +/* treat an object as fully ID'd when it might be used as reason for death */ +char * +killer_xname(obj) +struct obj *obj; +{ + struct obj save_obj; + unsigned save_ocknown; + char *buf, *save_ocuname; + + /* remember original settings for core of the object; + oname and oattached extensions don't matter here--since they + aren't modified they don't need to be saved and restored */ + save_obj = *obj; + /* killer name should be more specific than general xname; however, exact + info like blessed/cursed and rustproof makes things be too verbose */ + obj->known = obj->dknown = 1; + obj->bknown = obj->rknown = obj->greased = 0; + /* if character is a priest[ess], bknown will get toggled back on */ + obj->blessed = obj->cursed = 0; + /* "killed by poisoned " would be misleading when poison is + not the cause of death and "poisoned by poisoned " would + be redundant when it is, so suppress "poisoned" prefix */ + obj->opoisoned = 0; + /* strip user-supplied name; artifacts keep theirs */ + if (!obj->oartifact) obj->onamelth = 0; + /* temporarily identify the type of object */ + save_ocknown = objects[obj->otyp].oc_name_known; + objects[obj->otyp].oc_name_known = 1; + save_ocuname = objects[obj->otyp].oc_uname; + objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */ + + buf = xname(obj); + if (obj->quan == 1L) buf = obj_is_pname(obj) ? the(buf) : an(buf); + + objects[obj->otyp].oc_name_known = save_ocknown; + objects[obj->otyp].oc_uname = save_ocuname; + *obj = save_obj; /* restore object's core settings */ + + return buf; +} + /* * Used if only one of a collection of objects is named (e.g. in eat.c). */ diff --git a/src/trap.c b/src/trap.c index e696a920c..7c66c6a9e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)trap.c 3.4 2003/04/30 */ +/* SCCS Id: @(#)trap.c 3.4 2003/05/09 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -615,7 +615,7 @@ unsigned trflags; #endif if (thitu(7, dmgval(otmp, &youmonst), otmp, "little dart")) { if (otmp->opoisoned) - poisoned("dart",A_CON,"poison dart",10); + poisoned("dart", A_CON, "little dart", -10); obfree(otmp, (struct obj *)0); } else { place_object(otmp, u.ux, u.uy); -- 2.40.0