diff --git a/include/extern.h b/include/extern.h index 3a7cdcf52..8a94a16c1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1591017416 2020/06/01 13:16:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.848 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1593771615 2020/07/03 10:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.849 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -998,6 +998,7 @@ E void FDECL(record_achievement, (SCHAR_P)); E boolean FDECL(remove_achievement, (SCHAR_P)); E int NDECL(count_achievements); E schar FDECL(achieve_rank, (int)); +E boolean NDECL(sokoban_in_play); E int NDECL(dovanquished); E int NDECL(doborn); E void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P)); diff --git a/src/insight.c b/src/insight.c index 41ba4a254..b26e1efbf 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1593768047 2020/07/03 09:20:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1593771616 2020/07/03 10:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1769,7 +1769,7 @@ show_conduct(final) int final; { char buf[BUFSZ]; - int ngenocided, soko_ach; + int ngenocided; /* Create the conduct window */ g.en_win = create_nhwindow(NHW_MENU); @@ -1866,13 +1866,8 @@ int final; " for any artifacts", ""); } - /* only report Sokoban conduct if the Sokoban branch has been entered; - to find out whether that's the case, it's simpler to check the - recorded achievements than the convoluted dungeon data structure */ - for (soko_ach = 0; u.uachieved[soko_ach]; ++soko_ach) - if (u.uachieved[soko_ach] == ACH_SOKO) /* "entered Sokoban" */ - break; - if (u.uachieved[soko_ach]) { + /* only report Sokoban conduct if the Sokoban branch has been entered */ + if (sokoban_in_play()) { const char *presentverb = "have violated", *pastverb = "violated"; Strcpy(buf, " the special Sokoban rules "); @@ -2140,6 +2135,21 @@ int rank; /* 1..8 */ return achidx; } +/* return True if sokoban branch has been entered, False otherwise */ +boolean +sokoban_in_play() +{ + int achidx; + + /* TODO? move this to dungeon.c and test furthest level reached of the + sokoban branch instead of relying on the entered-sokoban achievement */ + + for (achidx = 0; u.uachieved[achidx]; ++achidx) + if (u.uachieved[achidx] == ACH_SOKO) + return TRUE; + return FALSE; +} + /* * Vanquished monsters. */ diff --git a/src/topten.c b/src/topten.c index 3141a58c7..73fee19a0 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 topten.c $NHDT-Date: 1581322668 2020/02/10 08:17:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 3.6 topten.c $NHDT-Date: 1593771616 2020/07/03 10:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -430,6 +430,15 @@ encodeconduct() e |= 1L << 10; if (!num_genocides()) e |= 1L << 11; + /* one bit isn't really adequate for sokoban conduct: + reporting "obeyed sokoban rules" is misleading if sokoban wasn't + completed or at least attempted; however, suppressing that when + sokoban was never entered, as we do here, risks reporting + "violated sokoban rules" when no such thing occured; this can + be disambiguated in xlogfile post-processors by testing the + entered-sokoban bit in the 'achieve' field */ + if (!u.uconduct.sokocheat && sokoban_in_play()) + e |= 1L << 12; return e; } @@ -582,6 +591,8 @@ encode_extended_conducts() add_achieveX(buf, "wishless", !u.uconduct.wishes); add_achieveX(buf, "artiwishless", !u.uconduct.wisharti); add_achieveX(buf, "genocideless", !num_genocides()); + if (sokoban_in_play()) + add_achieveX(buf, "sokoban", !u.uconduct.sokocheat); add_achieveX(buf, "blind", u.uroleplay.blind); add_achieveX(buf, "nudist", u.uroleplay.nudist);