From: PatR Date: Wed, 25 Aug 2021 22:02:26 +0000 (-0700) Subject: reveal elapsed time during play X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=573c4c0e635a0347bb4a11a30f55d92998ee974d;p=nethack reveal elapsed time during play Have end of game disclosure and the ^X command display the amount of time spent playing the current game instead of just putting that in xlogfile. This isn't an onscreen clock for speed runners as someone recently asked about on reddit. NetHack shouldn't attempt to handle that. --- diff --git a/src/insight.c b/src/insight.c index 6133919d2..908001c91 100644 --- a/src/insight.c +++ b/src/insight.c @@ -22,6 +22,7 @@ static void enlght_halfdmg(int, int); static boolean walking_on_water(void); static boolean cause_known(int); static char *attrval(int, int, char *); +static char *fmt_elapsed_time(char *, int); static void background_enlightenment(int, int); static void basics_enlightenment(int, int); static void characteristics_enlightenment(int, int); @@ -215,10 +216,69 @@ attrval(int attrindx, int attrvalue, return resultbuf; } +/* format urealtime.realtime as + " D days, H hours, M minutes and S seconds" + with any fields having a value of 0 omitted: + 0-00:00:20 => " 20 seconds" + 0-00:15:05 => " 15 minutes and 5 seconds" + 0-00:16:00 => " 16 minutes" + 0-01:15:10 => " 1 hour, 15 minutes and 10 seconds" + 0-02:00:01 => " 2 hours and 1 second" + 3-00:25:40 => " 3 days, 25 minutes and 40 seconds" + (note: for a list of more than two entries, nethack usually includes the + [style-wise] optional comma before "and" but in this instance it does not) + */ +static char * +fmt_elapsed_time(char *outbuf, int final) +{ + int fieldcnt; + long edays, ehours, eminutes, eseconds; + /* for a game that's over, reallydone() has updated urealtime.realtime + to its final value before calling us during end of game disclosure; + for a game that's still in progress, it holds the amount of elapsed + game time from previous sessions up through most recent save/restore + (or up through latest level change when 'checkpoint' is On); + '.start_timing' has a non-zero value even if '.realtime' is 0 */ + long etim = urealtime.realtime; + + if (!final) + etim += timet_delta(getnow(), urealtime.start_timing); + /* we could use localtime() to convert the value into a 'struct tm' + to get date and time fields but this is simple and straightforward */ + eseconds = etim % 60L, etim /= 60L; + eminutes = etim % 60L, etim /= 60L; + ehours = etim % 24L; + edays = etim / 24L; + fieldcnt = !!edays + !!ehours + !!eminutes + !!eseconds; + + Strcpy(outbuf, fieldcnt ? "" : " none"); /* 'none' should never happen */ + if (edays) { + Sprintf(eos(outbuf), " %ld day%s", edays, plur(edays)); + if (fieldcnt > 1) /* hours and/or minutes and/or seconds to follow */ + Strcat(outbuf, (fieldcnt == 2) ? " and" : ","); + --fieldcnt; /* edays has been processed */ + } + if (ehours) { + Sprintf(eos(outbuf), " %ld hour%s", ehours, plur(ehours)); + if (fieldcnt > 1) /* minutes and/or seconds to follow */ + Strcat(outbuf, (fieldcnt == 2) ? " and" : ","); + --fieldcnt; /* ehours has been processed */ + } + if (eminutes) { + Sprintf(eos(outbuf), " %ld minute%s", eminutes, plur(eminutes)); + if (fieldcnt > 1) /* seconds to follow */ + Strcat(outbuf, " and"); + /* eminutes has been processed but no need to decrement fieldcnt */ + } + if (eseconds) + Sprintf(eos(outbuf), " %ld second%s", eseconds, plur(eseconds)); + return outbuf; +} + void -enlightenment(int mode, /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */ - int final) /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, - ENL_GAMEOVERDEAD */ +enlightenment( + int mode, /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */ + int final) /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ { char buf[BUFSZ], tmpbuf[BUFSZ]; @@ -257,10 +317,11 @@ enlightenment(int mode, /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */ /* intrinsics and other traditional enlightenment feedback */ attributes_enlightenment(mode, final); } + + enlght_out(""); /* separator */ + enlght_out("Miscellaneous:"); /* reminder to player and/or information for dumplog */ if ((mode & BASICENLIGHTENMENT) != 0 && (wizard || discover || final)) { - enlght_out(""); /* separator */ - enlght_out("Miscellaneous:"); if (wizard || discover) { Sprintf(buf, "running in %s mode", wizard ? "debug" : "explore"); you_are(buf, ""); @@ -276,6 +337,8 @@ enlightenment(int mode, /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */ you_have_X(buf); } } + (void) fmt_elapsed_time(buf, final); + enl_msg("Total elapsed playing time ", "is", "was", buf, ""); if (!g.en_via_menu) { display_nhwindow(g.en_win, TRUE);