]> granicus.if.org Git - nethack/commitdiff
fix B02004 and other projectile related killer reasons
authornethack.rankin <nethack.rankin>
Wed, 14 May 2003 10:25:26 +0000 (10:25 +0000)
committernethack.rankin <nethack.rankin>
Wed, 14 May 2003 10:25:26 +0000 (10:25 +0000)
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
include/extern.h
src/mon.c
src/mthrowu.c
src/objnam.c
src/trap.c

index 78a4ad1dd8b3f41a79f71aa2e338800add895773..1bc43f4605dde4a022ec2fd7270c92f6fe03b3c8 100644 (file)
@@ -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
index abfe6be657c188fba1614f97f876cde8c5f70c14..2356a1950adfbe391d1fe4f8502fd8794bbe94b0 100644 (file)
@@ -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 *));
index 72c81f8e4dd7e8abb42854c5f5ec301111b26387..d49b801dad02521e1f70ff88307b57cf48098736 100644 (file)
--- 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();
 }
index e368b0994dd0f6085227695d27bc74c042d28d00..3038ced80c5ac6389aed1e392e76946b5b35021f 100644 (file)
@@ -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 <obj>" 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 <obj>" 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,
index bd9e0a6fca93ac5f4411e74d63551988e36599aa..472223f91c39425840ede022ac6227b07f0098db 100644 (file)
@@ -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 <obj>" would be misleading when poison is
+       not the cause of death and "poisoned by poisoned <obj>" 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).
  */
index e696a920c45c0cf164c2dae86a5ef9a81c21c37f..7c66c6a9e5196627c7c9b8d46a45a90281e652ce 100644 (file)
@@ -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);