]> granicus.if.org Git - nethack/commitdiff
fix bz 103+#H4095 - high scores ", while helpless"
authorPatR <rankin@nethack.org>
Fri, 18 Dec 2015 03:50:06 +0000 (19:50 -0800)
committerPatR <rankin@nethack.org>
Fri, 18 Dec 2015 03:50:06 +0000 (19:50 -0800)
If a character dies with 'multi' at a non-zero value, the reason for
helplessness is appended to the cause of death.  But that was taking
place in writeentry(), which is used for every score entry while
rewriting 'record' when a new high score is added.  So whenever a new
score with helplessness was added, all existing entries got corrupted
by having the newest game's reason for helplessness tacked on.

Append the helplessness reason while formatting the cause of death
instead of when writing out score and logfile entries.  xlogfile is
handled a little differently in case the cause of death plus reason
for helplessness is too long so truncated for record and logfile.
Full reason is still put into xlogfile.

doc/fixes36.1
src/rip.c
src/topten.c

index f68b47feedf6795a19e8ed199d8a20849818416f..bedec898646945936a41c5afe947da3440d5388a 100644 (file)
@@ -36,8 +36,10 @@ make a previously-discovered scroll written with marker while blind have its
        label known so it can be read while blind
 #name or C for discoveries list that spanned multiple pages would exit on
        space instead of advancing to next page (workaround: use '>' instead)
-don't show the old level when you die going down the stairs because of an 
+don't show the old level when you die going down the stairs because of an
         iron ball
+new high score with ", while helpless" attribute appended would erroneously
+       result in ", while helpless" being appended to all scores
 
 
 Platform- and/or Interface-Specific Fixes
index 80791cb8463eb566265029ce1757aed10111c831..c20cce2e23cc9930071ea6957fb9e68761c1021a 100644 (file)
--- a/src/rip.c
+++ b/src/rip.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 rip.c   $NHDT-Date: 1436753522 2015/07/13 02:12:02 $  $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
+/* NetHack 3.6 rip.c   $NHDT-Date: 1450410547 2015/12/18 03:49:07 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.21 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -91,7 +91,7 @@ time_t when;
 {
     register char **dp;
     register char *dpx;
-    char buf[BUFSZ];
+    char buf[BUFSZ], *p;
     long year;
     register int x;
     int line;
@@ -113,6 +113,9 @@ time_t when;
 
     /* Put together death description */
     formatkiller(buf, sizeof buf, how);
+    /* strip ", while helpless" to keep reason shorter */
+    if ((p = strstr(buf, ", while")) != 0)
+        *p = '\0';
 
     /* Put death type on stone */
     for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) {
index 375eb1d235445e7c09b433772429bd2197f7e957..553332352100b5433515b7f3bf93db116855a762 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 topten.c        $NHDT-Date: 1450231176 2015/12/16 01:59:36 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */
+/* NetHack 3.6 topten.c        $NHDT-Date: 1450410548 2015/12/18 03:49:08 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.42 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -64,10 +64,13 @@ STATIC_DCL void FDECL(outentry, (int, struct toptenentry *, BOOLEAN_P));
 STATIC_DCL void FDECL(discardexcess, (FILE *));
 STATIC_DCL void FDECL(readentry, (FILE *, struct toptenentry *));
 STATIC_DCL void FDECL(writeentry, (FILE *, struct toptenentry *));
+#ifdef XLOGFILE
 STATIC_DCL void FDECL(writexlentry, (FILE *, struct toptenentry *));
+STATIC_DCL char *FDECL(shortdeath, (char *, char *));
 STATIC_DCL long NDECL(encodexlogflags);
 STATIC_DCL long NDECL(encodeconduct);
 STATIC_DCL long NDECL(encodeachieve);
+#endif
 STATIC_DCL void FDECL(free_ttlist, (struct toptenentry *));
 STATIC_DCL int FDECL(classmon, (char *, BOOLEAN_P));
 STATIC_DCL int FDECL(score_wanted, (BOOLEAN_P, int, struct toptenentry *, int,
@@ -118,6 +121,17 @@ int how;
     /* we're writing into buf[0] (after possibly advancing buf) rather than
        appending, but strncat() appends a terminator and strncpy() doesn't */
     (void) strncat(buf, kname, siz - 1);
+
+    if (multi) {
+        siz -= strlen(buf);
+        buf = eos(buf);
+        /* X <= siz: 'sizeof "string"' includes 1 for '\0' terminator */
+        if (multi_reason && strlen(multi_reason) + sizeof ", while " <= siz)
+            Sprintf(buf, ", while %s", multi_reason);
+        else if (sizeof ", while helpless" <= siz)
+            Strcpy(buf, ", while helpless");
+        /* else extra death info won't fit, so leave it out */
+    }
 }
 
 STATIC_OVL void
@@ -269,10 +283,10 @@ struct toptenentry *tt;
     static const char fmt33[] = "%s %s %s %s "; /* role,race,gndr,algn */
 #ifndef NO_SCAN_BRACK
     static const char fmt0[] = "%d.%d.%d %ld %d %d %d %d %d %d %ld %ld %d ";
-    static const char fmtX[] = "%s,%s%s%s\n";
+    static const char fmtX[] = "%s,%s\n";
 #else /* NO_SCAN_BRACK */
     static const char fmt0[] = "%d %d %d %ld %d %d %d %d %d %d %ld %ld %d ";
-    static const char fmtX[] = "%s %s%s%s\n";
+    static const char fmtX[] = "%s %s\n";
 
     nsb_mung_line(tt->name);
     nsb_mung_line(tt->death);
@@ -288,9 +302,7 @@ struct toptenentry *tt;
         (void) fprintf(rfile, fmt33, tt->plrole, tt->plrace, tt->plgend,
                        tt->plalign);
     (void) fprintf(rfile, fmtX, onlyspace(tt->name) ? "_" : tt->name,
-                   tt->death,
-                   (multi ? ", while " : ""),
-                   (multi ? (multi_reason ? multi_reason : "helpless") : ""));
+                   tt->death);
 
 #ifdef NO_SCAN_BRACK
     nsb_unmung_line(tt->name);
@@ -298,6 +310,8 @@ struct toptenentry *tt;
 #endif
 }
 
+#ifdef XLOGFILE
+
 /* as tab is never used in eg. plname or death, no need to mangle those. */
 STATIC_OVL void
 writexlentry(rfile, tt)
@@ -306,7 +320,7 @@ struct toptenentry *tt;
 {
 #define Fprintf (void) fprintf
 #define XLOG_SEP '\t' /* xlogfile field separator. */
-    char buf[BUFSZ];
+    char buf[BUFSZ], tmpbuf[DTHSZ + 1];
 
     Sprintf(buf, "version=%d.%d.%d", tt->ver_major, tt->ver_minor,
             tt->patchlevel);
@@ -323,7 +337,7 @@ struct toptenentry *tt;
             tt->plalign);
     Fprintf(rfile, "%s%cname=%s%cdeath=%s",
             buf, /* (already includes separator) */
-            XLOG_SEP, plname, XLOG_SEP, tt->death);
+            XLOG_SEP, plname, XLOG_SEP, shortdeath(tmpbuf, tt->death));
     if (multi)
         Fprintf(rfile, "%cwhile=%s", XLOG_SEP,
                 multi_reason ? multi_reason : "helpless");
@@ -340,6 +354,20 @@ struct toptenentry *tt;
 #undef XLOG_SEP
 }
 
+/* used to strip ", while helpless" so xlogfile can show that separately
+   in case formatkiller() ending up truncating ", while "+multi_reason */
+STATIC_OVL char *
+shortdeath(outbuf, deathstring)
+char *outbuf, *deathstring;
+{
+    char *p;
+
+    Strcpy(outbuf, deathstring);
+    if ((p = strstr(outbuf, ", while")) != 0)
+        *p = '\0';
+    return outbuf;
+}
+
 STATIC_OVL long
 encodexlogflags()
 {
@@ -425,6 +453,8 @@ encodeachieve()
     return r;
 }
 
+#endif /* XLOGFILE */
+
 STATIC_OVL void
 free_ttlist(tt)
 struct toptenentry *tt;