From: PatR Date: Fri, 18 Dec 2015 03:50:06 +0000 (-0800) Subject: fix bz 103+#H4095 - high scores ", while helpless" X-Git-Tag: NetHack-3.6.1_RC01~1158 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20b2120f3f1b9888baad327f53a05b73d131d471;p=nethack fix bz 103+#H4095 - high scores ", while helpless" 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. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index f68b47fee..bedec8986 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -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 diff --git a/src/rip.c b/src/rip.c index 80791cb84..c20cce2e2 100644 --- 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++) { diff --git a/src/topten.c b/src/topten.c index 375eb1d23..553332352 100644 --- a/src/topten.c +++ b/src/topten.c @@ -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;