OPTIONS=scores:own

From a beta tester six years ago:  specifying 'scores:own' resulted
in an option setting of 'scores:3 top/2 around/own' when player
wanted 'scores:0 top/0 around/own'.  Change it so that when fewer
than all three fields are given new values, the others are reset
rather than having their old values merge with new settings.

Also, 'scores:none' can be used to get 'scores:0 top/0 around/!own'
to skip the scores at the end without skipping notification of
whether the ending game's score made it into the top N list.
Options parsing accepts '!scores' and then ignores the negation.
Changing the optlist flags for 'scores' to allow negation resulted
in a complaint about missing value; I gave up instead of pursuing
that.  'scores:none' should suffice.

Setting 'scores:!top/own' or 'scores:!around/own' would behave as
'scores:1 top/!own' or 'scores:1 around/!own', respectively.
'scores:!top/!around/own' behaved as 'scores:1 top/1 around/own'
(note affect of two prior negations on final field compared to
single negation in the earlier two variations).  This fixes those.
This commit is contained in:
PatR
2021-04-16 15:35:25 -07:00
parent cf62687630
commit 563ed2f7db
3 changed files with 94 additions and 66 deletions

View File

@@ -49,11 +49,13 @@ struct toptenentry {
char plalign[ROLESZ + 1];
char name[NAMSZ + 1];
char death[DTHSZ + 1];
} * tt_head;
} *tt_head;
/* size big enough to read in all the string fields at once; includes
room for separating space or trailing newline plus string terminator */
#define SCANBUFSZ (4 * (ROLESZ + 1) + (NAMSZ + 1) + (DTHSZ + 1) + 1)
static struct toptenentry zerott;
static void topten_print(const char *);
static void topten_print_bold(const char *);
static void outheader(void);
@@ -162,7 +164,7 @@ topten_print(const char *x)
}
static void
topten_print_bold(const char* x)
topten_print_bold(const char *x)
{
if (g.toptenwin == WIN_ERR)
raw_print_bold(x);
@@ -605,28 +607,20 @@ free_ttlist(struct toptenentry* tt)
void
topten(int how, time_t when)
{
int uid = getuid();
int rank, rank0 = -1, rank1 = 0;
int occ_cnt = sysopt.persmax;
register struct toptenentry *t0, *tprev;
struct toptenentry *t1;
FILE *rfile;
register int flg = 0;
boolean t0_used;
#ifdef LOGFILE
FILE *lfile;
#endif /* LOGFILE */
#endif
#ifdef XLOGFILE
FILE *xlfile;
#endif /* XLOGFILE */
#ifdef _DCC
/* Under DICE 3.0, this crashes the system consistently, apparently due to
* corruption of *rfile somewhere. Until I figure this out, just cut out
* topten support entirely - at least then the game exits cleanly. --AC
*/
return;
#endif
int uid = getuid();
int rank, rank0 = -1, rank1 = 0;
int occ_cnt = sysopt.persmax;
int flg = 0;
boolean t0_used, skip_scores;
/* If we are in the midst of a panic, cut out topten entirely.
* topten uses alloc() several times, which will lead to
@@ -651,6 +645,7 @@ topten(int how, time_t when)
/* create a new 'topten' entry */
t0_used = FALSE;
t0 = newttentry();
*t0 = zerott;
t0->ver_major = VERSION_MAJOR;
t0->ver_minor = VERSION_MINOR;
t0->patchlevel = PATCHLEVEL;
@@ -742,7 +737,7 @@ topten(int how, time_t when)
t1 = tt_head = newttentry();
tprev = 0;
/* rank0: -1 undefined, 0 not_on_list, n n_th on list */
for (rank = 1;;) {
for (rank = 1; ; ) {
readentry(rfile, t1);
if (t1->points < sysopt.pointsmin)
t1->points = 0;
@@ -774,7 +769,7 @@ topten(int how, time_t when)
char pbuf[BUFSZ];
Sprintf(pbuf,
"You didn't beat your previous score of %ld points.",
"You didn't beat your previous score of %ld points.",
t1->points);
topten_print(pbuf);
topten_print("");
@@ -823,43 +818,45 @@ topten(int how, time_t when)
topten_print("");
}
}
skip_scores = !flags.end_top && !flags.end_around && !flags.end_own;
if (rank0 == 0)
rank0 = rank1;
if (rank0 <= 0)
rank0 = rank;
if (!done_stopprint)
if (!skip_scores && !done_stopprint)
outheader();
t1 = tt_head;
for (rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
for (t1 = tt_head, rank = 1; t1->points != 0; t1 = t1->tt_next, ++rank) {
if (flg
#ifdef UPDATE_RECORD_IN_PLACE
&& rank >= rank0
#endif
)
writeentry(rfile, t1);
if (done_stopprint)
if (skip_scores || done_stopprint)
continue;
if (rank > flags.end_top && (rank < rank0 - flags.end_around
|| rank > rank0 + flags.end_around)
&& (!flags.end_own
|| (sysopt.pers_is_uid
? t1->uid == t0->uid
: strncmp(t1->name, t0->name, NAMSZ) == 0)))
continue;
if (rank == rank0 - flags.end_around
&& rank0 > flags.end_top + flags.end_around + 1 && !flags.end_own)
topten_print("");
if (rank != rank0)
outentry(rank, t1, FALSE);
else if (!rank1)
outentry(rank, t1, TRUE);
else {
outentry(rank, t1, TRUE);
outentry(0, t0, TRUE);
if (rank <= flags.end_top
|| (rank >= rank0 - flags.end_around
&& rank <= rank0 + flags.end_around)
|| (flags.end_own && (sysopt.pers_is_uid
? t1->uid == t0->uid
: !strncmp(t1->name, t0->name, NAMSZ)))) {
if (rank == rank0 - flags.end_around
&& rank0 > flags.end_top + flags.end_around + 1
&& !flags.end_own)
topten_print("");
if (rank != rank0) {
outentry(rank, t1, FALSE);
} else if (!rank1) {
outentry(rank, t1, TRUE);
} else {
outentry(rank, t1, TRUE);
outentry(0, t0, TRUE);
}
}
}
if (rank0 >= rank)
if (!done_stopprint)
if (!skip_scores && !done_stopprint)
outentry(0, t0, TRUE);
#ifdef UPDATE_RECORD_IN_PLACE
if (flg) {
@@ -868,16 +865,16 @@ topten(int how, time_t when)
truncate_file(rfile);
#else
/* use sentinel record rather than relying on truncation */
t1->points = 0L; /* terminates file when read back in */
t1->ver_major = t1->ver_minor = t1->patchlevel = 0;
t1->uid = t1->deathdnum = t1->deathlev = 0;
t1->maxlvl = t1->hp = t1->maxhp = t1->deaths = 0;
*t1 = zerott;
t1->points = 0L; /* [redundant] terminates file when read back in */
t1->plrole[0] = t1->plrace[0] = t1->plgend[0] = t1->plalign[0] = '-';
t1->plrole[1] = t1->plrace[1] = t1->plgend[1] = t1->plalign[1] = 0;
t1->birthdate = t1->deathdate = yyyymmdd((time_t) 0L);
Strcpy(t1->name, "@");
Strcpy(t1->death, "<eod>\n");
Strcpy(t1->death, "<eod>\n"); /* end of data */
writeentry(rfile, t1);
/* note: there might be junk (if file has shrunk due to shorter
entries supplanting longer ones) after this dummy entry, but
reading and/or updating will ignore it */
(void) fflush(rfile);
#endif /* TRUNCATE_FILE */
}
@@ -886,10 +883,10 @@ topten(int how, time_t when)
unlock_file(RECORD);
free_ttlist(tt_head);
showwin:
showwin:
if (iflags.toptenwin && !done_stopprint)
display_nhwindow(g.toptenwin, 1);
destroywin:
destroywin:
if (!t0_used)
dealloc_ttentry(t0);
if (iflags.toptenwin) {
@@ -1310,7 +1307,7 @@ get_rnd_toptenentry(void)
tt = &tt_buf;
rank = rnd(sysopt.tt_oname_maxrank);
pickentry:
pickentry:
for (i = rank; i; i--) {
readentry(rfile, tt);
if (tt->points == 0)