diff --git a/include/context.h b/include/context.h index 0e7595ff9..bddc8e94b 100644 --- a/include/context.h +++ b/include/context.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 context.h $NHDT-Date: 1445215010 2015/10/19 00:36:50 $ $NHDT-Branch: master $:$NHDT-Revision: 1.27 $ */ +/* NetHack 3.6 context.h $NHDT-Date: 1447653421 2015/11/16 05:57:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -90,6 +90,12 @@ struct tribute_info { /* 30 free bits */ }; +struct novel_tracking { /* for choosing random passage when reading novel */ + unsigned id; /* novel oid from previous passage selection */ + int count; /* number of passage indices available in pasg[] */ + xchar pasg[30]; /* pasg[0..count] are passage indices */ +}; + struct context_info { unsigned ident; /* social security number for each monster */ unsigned no_of_wizards; /* 0, 1 or 2 (wizard and his shadow) */ @@ -124,6 +130,7 @@ struct context_info { struct polearm_info polearm; struct obj_split objsplit; /* track most recently split object stack */ struct tribute_info tribute; + struct novel_tracking novel; }; extern NEARDATA struct context_info context; diff --git a/include/extern.h b/include/extern.h index 5add97a44..2b96c74e8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1447475941 2015/11/14 04:39:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.516 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1447653422 2015/11/16 05:57:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.517 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -766,7 +766,8 @@ E void NDECL(really_close); #ifdef DEBUG E boolean FDECL(debugcore, (const char *, BOOLEAN_P)); #endif -E boolean FDECL(read_tribute, (const char *, const char *, int, char *, int)); +E boolean FDECL(read_tribute, (const char *, const char *, int, + char *, int, unsigned)); E boolean FDECL(Death_quote, (char *, int)); /* ### fountain.c ### */ diff --git a/include/patchlevel.h b/include/patchlevel.h index cbc717e54..2beb4bf15 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 patchlevel.h $NHDT-Date: 1447311411 2015/11/12 06:56:51 $ $NHDT-Branch: master $:$NHDT-Revision: 1.110 $ */ +/* NetHack 3.6 patchlevel.h $NHDT-Date: 1447653420 2015/11/16 05:57:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -13,7 +13,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 0 +#define EDITLEVEL 2 #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2015" #define COPYRIGHT_BANNER_B \ diff --git a/src/files.c b/src/files.c index f9638681c..f257046f6 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1446955299 2015/11/08 04:01:39 $ $NHDT-Branch: master $:$NHDT-Revision: 1.186 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1447653425 2015/11/16 05:57:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.187 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3421,20 +3421,55 @@ boolean wildcards; /* ---------- BEGIN TRIBUTE ----------- */ /* 3.6 tribute code - * - * Returns TRUE if you were able to read something. - * */ #define SECTIONSCOPE 1 #define TITLESCOPE 2 #define PASSAGESCOPE 3 +#define MAXPASSAGES SIZE(context.novel.pasg) /* 30 */ + +static int FDECL(choose_passage, (int, unsigned)); + +/* choose a random passage that hasn't been chosen yet; once all have + been chosen, reset the tracking to make all passages available again */ +static int +choose_passage(passagecnt, oid) +int passagecnt; /* total of available passages, 1..MAXPASSAGES */ +unsigned oid; /* book.o_id, used to determine whether re-reading same book */ +{ + int idx, res; + + if (passagecnt < 1) + return 0; + if (passagecnt > MAXPASSAGES) + passagecnt = MAXPASSAGES; + + /* if a different book or we've used up all the passages already, + reset in order to have all 'passagecnt' passages available */ + if (oid != context.novel.id || context.novel.count == 0) { + context.novel.id = oid; + context.novel.count = passagecnt; + for (idx = 0; idx < MAXPASSAGES; idx++) + context.novel.pasg[idx] = (xchar) ((idx < passagecnt) ? idx + 1 + : 0); + } + + idx = rn2(context.novel.count); + res = (int) context.novel.pasg[idx]; + /* move the last slot's passage index into the slot just used + and reduce the number of passages available */ + context.novel.pasg[idx] = context.novel.pasg[--context.novel.count]; + return res; +} + +/* Returns True if you were able to read something. */ boolean -read_tribute(tribsection, tribtitle, tribpassage, nowin_buf, bufsz) +read_tribute(tribsection, tribtitle, tribpassage, nowin_buf, bufsz, oid) const char *tribsection, *tribtitle; int tribpassage, bufsz; char *nowin_buf; +unsigned oid; /* book identifier */ { dlb *fp; char *endp; @@ -3510,22 +3545,17 @@ char *nowin_buf; if ((p2 = index(p1, ')')) != 0) { *p2 = '\0'; passagecnt = atoi(p1); - /* sanity check here caps #passages at 50 */ - if ((passagecnt > 0) && (passagecnt < 50)) { - scope = TITLESCOPE; - if (matchedsection && !strcmpi(st, tribtitle)) { - matchedtitle = TRUE; - if (!tribpassage) { - targetpassage = rnd(passagecnt); - } else { - if (tribpassage <= passagecnt) - targetpassage = tribpassage; - else - targetpassage = 0; - } - } else { - matchedtitle = FALSE; - } + if (passagecnt > MAXPASSAGES) + passagecnt = MAXPASSAGES; + scope = TITLESCOPE; + if (matchedsection && !strcmpi(st, tribtitle)) { + matchedtitle = TRUE; + targetpassage = !tribpassage + ? choose_passage(passagecnt, oid) + : (tribpassage <= passagecnt) + ? tribpassage : 0; + } else { + matchedtitle = FALSE; } } } @@ -3610,8 +3640,11 @@ Death_quote(buf, bufsz) char *buf; int bufsz; { - return read_tribute("Death", "Death Quotes", 0, buf, bufsz); + unsigned death_oid = 1; /* chance of oid #1 being a novel is negligible */ + + return read_tribute("Death", "Death Quotes", 0, buf, bufsz, death_oid); } + /* ---------- END TRIBUTE ----------- */ /*files.c*/ diff --git a/src/spell.c b/src/spell.c index 75fe0b50b..71068c7a6 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 spell.c $NHDT-Date: 1446854236 2015/11/06 23:57:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.6 spell.c $NHDT-Date: 1447653429 2015/11/16 05:57:09 $ $NHDT-Branch: master $:$NHDT-Revision: 1.72 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ @@ -469,7 +469,9 @@ register struct obj *spellbook; if (booktype == SPE_NOVEL) { /* Obtain current Terry Pratchett book title */ const char *tribtitle = noveltitle(&spellbook->novelidx); - if (read_tribute("books", tribtitle, 0, (char *)0, 0)) { + + if (read_tribute("books", tribtitle, 0, (char *) 0, 0, + spellbook->o_id)) { u.uconduct.literate++; check_unpaid(spellbook); if (!u.uevent.read_tribute) {