-/* 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. */
/* 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) */
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;
-/* 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. */
#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 ### */
-/* 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. */
/* ---------- 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;
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;
}
}
}
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*/
-/* 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. */
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) {