… | |
… | |
31 | #include <global.h> |
31 | #include <global.h> |
32 | #include <book.h> |
32 | #include <book.h> |
33 | #include <living.h> |
33 | #include <living.h> |
34 | #include <spells.h> |
34 | #include <spells.h> |
35 | |
35 | |
36 | /* Define this if you want to archive book titles by contents. |
36 | /* Define this if you want to archive book titles by contents. |
37 | * This option should enforce UNIQUE combinations of titles,authors and |
37 | * This option should enforce UNIQUE combinations of titles,authors and |
38 | * msg contents during and *between* game sessions. |
38 | * msg contents during and *between* game sessions. |
39 | * Note: a slight degeneracy exists since books are archived based on an integer |
39 | * Note: a slight degeneracy exists since books are archived based on an integer |
40 | * index value calculated from the message text (similar to alchemy formulae). |
40 | * index value calculated from the message text (similar to alchemy formulae). |
41 | * Sometimes two widely different messages have the same index value (rare). In |
41 | * Sometimes two widely different messages have the same index value (rare). In |
42 | * this case, it is possible to occasionally generate 2 books with same title and |
42 | * this case, it is possible to occasionally generate 2 books with same title and |
43 | * different message content. Not really a bug, but rather a feature. This action |
43 | * different message content. Not really a bug, but rather a feature. This action |
44 | * should keeps player on their toes ;). |
44 | * should keeps player on their toes ;). |
45 | * Also, note that there is *finite* space available for archiving message and titles. |
45 | * Also, note that there is *finite* space available for archiving message and titles. |
46 | * Once this space is used, books will stop being archived. Not a serious problem |
46 | * Once this space is used, books will stop being archived. Not a serious problem |
47 | * under the current regime, since there are generally fewer possible (random) |
47 | * under the current regime, since there are generally fewer possible (random) |
48 | * messages than space available on the titlelists. |
48 | * messages than space available on the titlelists. |
49 | * One exception (for sure) are the monster messages. But no worries, you should |
49 | * One exception (for sure) are the monster messages. But no worries, you should |
50 | * see all of the monster info in some order (but not all possble combinations) |
50 | * see all of the monster info in some order (but not all possble combinations) |
51 | * before the monster titlelist space is run out. You can increase titlelist |
51 | * before the monster titlelist space is run out. You can increase titlelist |
52 | * space by increasing the array sizes for the monster book_authours and book_names |
52 | * space by increasing the array sizes for the monster book_authours and book_names |
53 | * (see max_titles[] array and include/read.h). Since the unique_book algorthm is |
53 | * (see max_titles[] array and include/read.h). Since the unique_book algorthm is |
54 | * kinda stupid, this program *may* slow down program execution if defined (but I don't |
54 | * kinda stupid, this program *may* slow down program execution if defined (but I don't |
55 | * think its a significant problem, at least, I have no problems running this option |
55 | * think its a significant problem, at least, I have no problems running this option |
56 | * on a Sparc 10! Also, once archive title lists are filled and/or all possible msg |
56 | * on a Sparc 10! Also, once archive title lists are filled and/or all possible msg |
57 | * combinations have been generated, unique_book isnt called anymore. It takes 5-10 |
57 | * combinations have been generated, unique_book isnt called anymore. It takes 5-10 |
58 | * sessions for this to happen). |
58 | * sessions for this to happen). |
59 | * Final note: the game remembers book/title/msg combinations from reading the |
59 | * Final note: the game remembers book/title/msg combinations from reading the |
60 | * file lib/bookarch. If you REMOVE this file, you will lose your archive. So |
60 | * file lib/bookarch. If you REMOVE this file, you will lose your archive. So |
61 | * be sure to copy it over to the new lib directory when you change versions. |
61 | * be sure to copy it over to the new lib directory when you change versions. |
62 | * -b.t. |
62 | * -b.t. |
63 | */ |
63 | */ |
64 | |
64 | |
65 | /* This flag is useful to see what kind of output messages are created */ |
65 | /* This flag is useful to see what kind of output messages are created */ |
66 | |
66 | |
… | |
… | |
555 | } |
555 | } |
556 | |
556 | |
557 | return tl; |
557 | return tl; |
558 | } |
558 | } |
559 | |
559 | |
560 | /* HANDMADE STRING FUNCTIONS.., perhaps these belong in another file |
560 | /* HANDMADE STRING FUNCTIONS.., perhaps these belong in another file |
561 | * (shstr.c ?), but the quantity BOOK_BUF will need to be defined. */ |
561 | * (shstr.c ?), but the quantity BOOK_BUF will need to be defined. */ |
562 | |
562 | |
563 | /* nstrtok() - simple routine to return the number of list |
563 | /* nstrtok() - simple routine to return the number of list |
564 | * items in buf1 as separated by the value of buf2 |
564 | * items in buf1 as separated by the value of buf2 |
565 | */ |
565 | */ |
… | |
… | |
691 | LOG (llevDebug, " (%d/%d)\n", bl->number, max_titles[i]); |
691 | LOG (llevDebug, " (%d/%d)\n", bl->number, max_titles[i]); |
692 | |
692 | |
693 | LOG (llevDebug, "init_book_archive() got %d titles.\n", nroftitle); |
693 | LOG (llevDebug, "init_book_archive() got %d titles.\n", nroftitle); |
694 | } |
694 | } |
695 | |
695 | |
696 | /* init_mon_info() - creates the linked list of pointers to |
696 | /* init_mon_info() - creates the linked list of pointers to |
697 | * monster archetype objects if not called previously |
697 | * monster archetype objects if not called previously |
698 | */ |
698 | */ |
699 | static void |
699 | static void |
700 | init_mon_info () |
700 | init_mon_info () |
701 | { |
701 | { |
… | |
… | |
721 | } |
721 | } |
722 | |
722 | |
723 | LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon); |
723 | LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon); |
724 | } |
724 | } |
725 | |
725 | |
726 | /* init_readable() - initialise linked lists utilized by |
726 | /* init_readable() - initialise linked lists utilized by |
727 | * message functions in tailor_readable_ob() |
727 | * message functions in tailor_readable_ob() |
728 | * |
728 | * |
729 | * This is the function called by the main routine to initialise |
729 | * This is the function called by the main routine to initialise |
730 | * all the readable information. |
730 | * all the readable information. |
731 | */ |
731 | */ |
732 | void |
732 | void |
… | |
… | |
782 | |
782 | |
783 | return t; |
783 | return t; |
784 | } |
784 | } |
785 | |
785 | |
786 | /* new_text_name() - Only for objects of type BOOK. SPELLBOOK stuff is |
786 | /* new_text_name() - Only for objects of type BOOK. SPELLBOOK stuff is |
787 | * handled directly in change_book_name(). Names are based on text |
787 | * handled directly in change_book_name(). Names are based on text |
788 | * msgtype |
788 | * msgtype |
789 | * this sets book book->name based on msgtype given. What name |
789 | * this sets book book->name based on msgtype given. What name |
790 | * is given is based on various criteria |
790 | * is given is based on various criteria |
791 | */ |
791 | */ |
792 | static void |
792 | static void |
… | |
… | |
861 | } |
861 | } |
862 | |
862 | |
863 | op->title = format ("of %s", name); |
863 | op->title = format ("of %s", name); |
864 | } |
864 | } |
865 | |
865 | |
866 | /* unique_book() - check to see if the book title/msg is unique. We |
866 | /* unique_book() - check to see if the book title/msg is unique. We |
867 | * go through the entire list of possibilities each time. If we find |
867 | * go through the entire list of possibilities each time. If we find |
868 | * a match, then unique_book returns true (because inst unique). |
868 | * a match, then unique_book returns true (because inst unique). |
869 | */ |
869 | */ |
870 | |
870 | |
871 | static int |
871 | static int |
… | |
… | |
918 | #endif |
918 | #endif |
919 | |
919 | |
920 | } |
920 | } |
921 | |
921 | |
922 | |
922 | |
923 | /* change_book() - give a new, fancier name to generated |
923 | /* change_book() - give a new, fancier name to generated |
924 | * objects of type BOOK and SPELLBOOK. |
924 | * objects of type BOOK and SPELLBOOK. |
925 | * Aug 96 I changed this so we will attempt to create consistent |
925 | * Aug 96 I changed this so we will attempt to create consistent |
926 | * authour/title and message content for BOOKs. Also, we will |
926 | * authour/title and message content for BOOKs. Also, we will |
927 | * alter books that match archive entries to the archival |
927 | * alter books that match archive entries to the archival |
928 | * levels and architypes. -b.t. |
928 | * levels and architypes. -b.t. |
929 | */ |
929 | */ |
930 | |
930 | |
931 | #define MAX_TITLE_CHECK 20 |
931 | #define MAX_TITLE_CHECK 20 |
932 | |
932 | |
933 | static void |
933 | static void |
… | |
… | |
943 | title *t = NULL; |
943 | title *t = NULL; |
944 | int tries = 0; |
944 | int tries = 0; |
945 | |
945 | |
946 | /* look to see if our msg already been archived. If so, alter |
946 | /* look to see if our msg already been archived. If so, alter |
947 | * the book to match the archival text. If we fail to match, |
947 | * the book to match the archival text. If we fail to match, |
948 | * then we archive the new title/name/msg combo if there is |
948 | * then we archive the new title/name/msg combo if there is |
949 | * room on the titlelist. |
949 | * room on the titlelist. |
950 | */ |
950 | */ |
951 | |
951 | |
952 | if ((strlen (book->msg) > 5) && (t = find_title (book, msgtype))) |
952 | if ((strlen (book->msg) > 5) && (t = find_title (book, msgtype))) |
953 | { |
953 | { |
954 | /* alter book properties */ |
954 | /* alter book properties */ |
… | |
… | |
1004 | |
1004 | |
1005 | /* Now deal with 2 cases. |
1005 | /* Now deal with 2 cases. |
1006 | * 1)If no space for a new title exists lets just restore |
1006 | * 1)If no space for a new title exists lets just restore |
1007 | * the old book properties. Remember, if the book had |
1007 | * the old book properties. Remember, if the book had |
1008 | * matchd an older entry on the titlelist, we shouldnt |
1008 | * matchd an older entry on the titlelist, we shouldnt |
1009 | * have called this routine in the first place! |
1009 | * have called this routine in the first place! |
1010 | * 2) If we got a unique title, we need to add it to |
1010 | * 2) If we got a unique title, we need to add it to |
1011 | * the list. |
1011 | * the list. |
1012 | */ |
1012 | */ |
1013 | |
1013 | |
1014 | if (tries == MAX_TITLE_CHECK || numb == maxnames) |
1014 | if (tries == MAX_TITLE_CHECK || numb == maxnames) |
… | |
… | |
1048 | |
1048 | |
1049 | /***************************************************************************** |
1049 | /***************************************************************************** |
1050 | * Monster msg generation code. |
1050 | * Monster msg generation code. |
1051 | ****************************************************************************/ |
1051 | ****************************************************************************/ |
1052 | |
1052 | |
1053 | /* get_random_mon() - returns a random monster slected from linked |
1053 | /* get_random_mon() - returns a random monster slected from linked |
1054 | * list of all monsters in the current game. If level is non-zero, |
1054 | * list of all monsters in the current game. If level is non-zero, |
1055 | * then only monsters greater than that level will be returned. |
1055 | * then only monsters greater than that level will be returned. |
1056 | * Changed 971225 to be greater than equal to level passed. Also |
1056 | * Changed 971225 to be greater than equal to level passed. Also |
1057 | * made choosing by level more random. |
1057 | * made choosing by level more random. |
1058 | */ |
1058 | */ |
… | |
… | |
1084 | } |
1084 | } |
1085 | |
1085 | |
1086 | /* Case where we are searching by level. Redone 971225 to be clearer |
1086 | /* Case where we are searching by level. Redone 971225 to be clearer |
1087 | * and more random. Before, it looks like it took a random monster from |
1087 | * and more random. Before, it looks like it took a random monster from |
1088 | * the list, and then returned the first monster after that which was |
1088 | * the list, and then returned the first monster after that which was |
1089 | * appropriate level. This wasn't very random because if you had a |
1089 | * appropriate level. This wasn't very random because if you had a |
1090 | * bunch of low level monsters and then a high level one, if the random |
1090 | * bunch of low level monsters and then a high level one, if the random |
1091 | * determine took one of the low level ones, it would just forward to the |
1091 | * determine took one of the low level ones, it would just forward to the |
1092 | * high level one and return that. Thus, monsters that immediatly followed |
1092 | * high level one and return that. Thus, monsters that immediatly followed |
1093 | * a bunch of low level monsters would be more heavily returned. It also |
1093 | * a bunch of low level monsters would be more heavily returned. It also |
1094 | * means some of the dragons would be poorly represented, since they |
1094 | * means some of the dragons would be poorly represented, since they |
… | |
… | |
1157 | else |
1157 | else |
1158 | return first_mon_info->ob; |
1158 | return first_mon_info->ob; |
1159 | |
1159 | |
1160 | } |
1160 | } |
1161 | |
1161 | |
1162 | /* mon_info_msg() - generate a message detailing the properties |
1162 | /* mon_info_msg() - generate a message detailing the properties |
1163 | * of a randomly selected monster. |
1163 | * of a randomly selected monster. |
1164 | */ |
1164 | */ |
1165 | static const char * |
1165 | static const char * |
1166 | mon_info_msg (int level) |
1166 | mon_info_msg (int level) |
1167 | { |
1167 | { |
1168 | static dynbuf_text buf; buf.clear (); |
1168 | static dynbuf_text buf; buf.clear (); |
1169 | |
1169 | |
1170 | /*preamble */ |
1170 | /*preamble */ |
1171 | buf << "This beastiary contains:\n"; |
1171 | buf << "This beastiary contains:\n"; |
1172 | |
1172 | |
1173 | /* lets print info on as many monsters as will fit in our |
1173 | /* lets print info on as many monsters as will fit in our |
1174 | * document. |
1174 | * document. |
1175 | * 8-96 Had to change this a bit, otherwise there would |
1175 | * 8-96 Had to change this a bit, otherwise there would |
1176 | * have been an impossibly large number of combinations |
1176 | * have been an impossibly large number of combinations |
1177 | * of text! (and flood out the available number of titles |
1177 | * of text! (and flood out the available number of titles |
1178 | * in the archive in a snap!) -b.t. |
1178 | * in the archive in a snap!) -b.t. |
1179 | */ |
1179 | */ |
1180 | object *tmp = get_random_mon (level * 3); |
1180 | object *tmp = get_random_mon (level * 3); |
1181 | while (tmp && buf.size () < BOOK_BUF) |
1181 | while (tmp && buf.size () < BOOK_BUF) |
1182 | { |
1182 | { |
1183 | /* monster description */ |
1183 | /* monster description */ |
… | |
… | |
1251 | buf.printf ("Herein %s detailed %s...\n", |
1251 | buf.printf ("Herein %s detailed %s...\n", |
1252 | book_entries > 1 ? "are" : "is", |
1252 | book_entries > 1 ? "are" : "is", |
1253 | book_entries > 1 ? "some artifacts" : "an artifact"); |
1253 | book_entries > 1 ? "some artifacts" : "an artifact"); |
1254 | |
1254 | |
1255 | /* artifact msg attributes loop. Lets keep adding entries to the 'book' |
1255 | /* artifact msg attributes loop. Lets keep adding entries to the 'book' |
1256 | * as long as we have space up to the allowed max # (book_entires) |
1256 | * as long as we have space up to the allowed max # (book_entires) |
1257 | */ |
1257 | */ |
1258 | while (book_entries > 0 && buf.size () < BOOK_BUF) |
1258 | while (book_entries > 0 && buf.size () < BOOK_BUF) |
1259 | { |
1259 | { |
1260 | |
1260 | |
1261 | if (!art) |
1261 | if (!art) |
… | |
… | |
1322 | /***************************************************************************** |
1322 | /***************************************************************************** |
1323 | * Spellpath message generation |
1323 | * Spellpath message generation |
1324 | *****************************************************************************/ |
1324 | *****************************************************************************/ |
1325 | |
1325 | |
1326 | /* spellpath_msg() - generate a message detailing the member |
1326 | /* spellpath_msg() - generate a message detailing the member |
1327 | * incantations/prayers (and some of their properties) belonging to |
1327 | * incantations/prayers (and some of their properties) belonging to |
1328 | * a given spellpath. |
1328 | * a given spellpath. |
1329 | */ |
1329 | */ |
1330 | static char * |
1330 | static char * |
1331 | spellpath_msg (int level) |
1331 | spellpath_msg (int level) |
1332 | { |
1332 | { |
1333 | static dynbuf_text buf; buf.clear (); |
1333 | static dynbuf_text buf; buf.clear (); |
… | |
… | |
1381 | int chance; |
1381 | int chance; |
1382 | |
1382 | |
1383 | static dynbuf_text buf; buf.clear (); |
1383 | static dynbuf_text buf; buf.clear (); |
1384 | |
1384 | |
1385 | /* the higher the book level, the more complex (ie number of |
1385 | /* the higher the book level, the more complex (ie number of |
1386 | * ingredients) the formula can be. |
1386 | * ingredients) the formula can be. |
1387 | */ |
1387 | */ |
1388 | fl = get_formulalist (rndm (level) / 3 + 1); |
1388 | fl = get_formulalist (rndm (level) / 3 + 1); |
1389 | |
1389 | |
1390 | if (!fl) |
1390 | if (!fl) |
1391 | fl = get_formulalist (1); /* safety */ |
1391 | fl = get_formulalist (1); /* safety */ |