]> granicus.if.org Git - nethack/commitdiff
tribute enhancement
authorPatR <rankin@nethack.org>
Mon, 16 Nov 2015 05:57:15 +0000 (21:57 -0800)
committerPatR <rankin@nethack.org>
Mon, 16 Nov 2015 05:57:15 +0000 (21:57 -0800)
When reading a novel, select a random passage which hasn't been shown
already.  Once you've run through all the passages, it resets to get
them all again (with new random order that might happen to the be same
order if there aren't many passages).  Switching to a different novel--
even another copy of the same one--will cause the previous passage
selection to be discarded and restarted from scratch if the prior book
is read again.  Passage tracking for the most recently read novel is
kept across save and restore.  (That means I needed to bump EDITLEVEL,
so it will need to be reset to 0 again before release.)

include/context.h
include/extern.h
include/patchlevel.h
src/files.c
src/spell.c

index 0e7595ff929c7e1201a9e6d0d47d96a2ac29397c..bddc8e94be196185444fadb3bca2ee13f311c389 100644 (file)
@@ -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;
index 5add97a441de0056fed3a0124f75e345a2a30b83..2b96c74e86b9d685c4ac2cf25a0dc21d2d7b38a0 100644 (file)
@@ -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 ### */
index cbc717e54a4a2fe7d24f288114b11a2956410b5f..2beb4bf157c49d3539d437179ef126d2228787ad 100644 (file)
@@ -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 \
index f9638681c1a2b3e638a554b56d622ddc83375684..f257046f653bac87f017ab7f5050a34828db9c54 100644 (file)
@@ -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*/
index 75fe0b50b3076a0c14854af4bdd4868f67ec337d..71068c7a6cb3fff89f117bfa7b079b70453a93eb 100644 (file)
@@ -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) {