--- deliantra/server/common/readable.C 2009/10/15 23:25:53 1.48 +++ deliantra/server/common/readable.C 2017/01/29 02:47:04 1.68 @@ -1,24 +1,24 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. - * - * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team - * Copyright (©) 1992,2007 Frank Tore Johansen - * + * + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2002 Mark Wedel & Crossfire Development Team + * Copyright (©) 1992 Frank Tore Johansen + * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ @@ -33,32 +33,32 @@ #include #include -/* Define this if you want to archive book titles by contents. - * This option should enforce UNIQUE combinations of titles,authors and - * msg contents during and *between* game sessions. - * Note: a slight degeneracy exists since books are archived based on an integer - * index value calculated from the message text (similar to alchemy formulae). - * Sometimes two widely different messages have the same index value (rare). In - * this case, it is possible to occasionally generate 2 books with same title and - * different message content. Not really a bug, but rather a feature. This action - * should keeps player on their toes ;). - * Also, note that there is *finite* space available for archiving message and titles. - * Once this space is used, books will stop being archived. Not a serious problem - * under the current regime, since there are generally fewer possible (random) +/* Define this if you want to archive book titles by contents. + * This option should enforce UNIQUE combinations of titles,authors and + * msg contents during and *between* game sessions. + * Note: a slight degeneracy exists since books are archived based on an integer + * index value calculated from the message text (similar to alchemy formulae). + * Sometimes two widely different messages have the same index value (rare). In + * this case, it is possible to occasionally generate 2 books with same title and + * different message content. Not really a bug, but rather a feature. This action + * should keeps player on their toes ;). + * Also, note that there is *finite* space available for archiving message and titles. + * Once this space is used, books will stop being archived. Not a serious problem + * under the current regime, since there are generally fewer possible (random) * messages than space available on the titlelists. * One exception (for sure) are the monster messages. But no worries, you should * see all of the monster info in some order (but not all possble combinations) * before the monster titlelist space is run out. You can increase titlelist - * space by increasing the array sizes for the monster book_authours and book_names - * (see max_titles[] array and include/read.h). Since the unique_book algorthm is - * kinda stupid, this program *may* slow down program execution if defined (but I don't + * space by increasing the array sizes for the monster book_authours and book_names + * (see max_titles[] array and include/read.h). Since the unique_book algorthm is + * kinda stupid, this program *may* slow down program execution if defined (but I don't * think its a significant problem, at least, I have no problems running this option - * on a Sparc 10! Also, once archive title lists are filled and/or all possible msg - * combinations have been generated, unique_book isnt called anymore. It takes 5-10 - * sessions for this to happen). + * on a Sparc 10! Also, once archive title lists are filled and/or all possible msg + * combinations have been generated, unique_book isnt called anymore. It takes 5-10 + * sessions for this to happen). * Final note: the game remembers book/title/msg combinations from reading the * file lib/bookarch. If you REMOVE this file, you will lose your archive. So - * be sure to copy it over to the new lib directory when you change versions. + * be sure to copy it over to the new lib directory when you change versions. * -b.t. */ @@ -110,20 +110,9 @@ static int nrofmon = 0, need_to_write_bookarchive = 0; - -/* this is needed to keep track of status of initialisation - * of the message file */ -static int nrofmsg = 0; - -/* first_msg is the started of the linked list of messages as read from - * the messages file - */ -static linked_char *first_msg = NULL; - /* * Spellpath information */ - static uint32 spellpathdef[NRSPELLPATHS] = { PATH_PROT, PATH_FIRE, @@ -414,7 +403,7 @@ "cryptic", "cryptical", "dusty", - "hiearchical", + "hierarchical", "grizzled", "gold-guilt", "great", @@ -499,7 +488,7 @@ {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_2, "readable-monument-wall-2"}, {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_3, "readable-monument-wall-3"} }; -int last_readable_subtype = sizeof (readable_message_types) / sizeof (readable_message_type); +static int last_readable_subtype = sizeof (readable_message_types) / sizeof (readable_message_type); static int max_titles[6] = { ((sizeof (light_book_name) / sizeof (char *)) + (sizeof (heavy_book_name) / sizeof (char *))) * (sizeof (book_author) / sizeof (char *)), @@ -517,7 +506,7 @@ *****************************************************************************/ static titlelist * -get_empty_booklist (void) +get_empty_booklist () { titlelist *bl = new titlelist; @@ -528,7 +517,7 @@ } static title * -get_empty_book (void) +get_empty_book () { title *t = new title; @@ -547,6 +536,9 @@ static titlelist * get_titlelist (int i) { + if (!booklist) + booklist = get_empty_booklist (); + titlelist *tl = booklist; int number = i; @@ -559,13 +551,13 @@ tl->next = get_empty_booklist (); tl = tl->next; - number--; + --number; } return tl; } -/* HANDMADE STRING FUNCTIONS.., perhaps these belong in another file +/* HANDMADE STRING FUNCTIONS.., perhaps these belong in another file * (shstr.c ?), but the quantity BOOK_BUF will need to be defined. */ /* nstrtok() - simple routine to return the number of list @@ -579,8 +571,10 @@ if (!buf1 || !buf2) return 0; - sprintf (buf, "%s", buf1); - sprintf (sbuf, "%s", buf2); + + strcpy (buf, buf1); + strcpy (sbuf, buf2); + tbuf = strtok (buf, sbuf); while (tbuf) { @@ -609,6 +603,7 @@ while (tbuf && i > 0) { strcat (rbuf, tbuf); + i--; if (i == 1 && maxi > 1) strcat (rbuf, " and "); @@ -616,19 +611,11 @@ strcat (rbuf, ", "); else strcat (rbuf, "."); + tbuf = strtok (NULL, sbuf); } - return (char *) rbuf; -} -static int -book_overflow (const char *buf1, const char *buf2, int booksize) -{ - if (buf_overflow (buf1, buf2, BOOK_BUF - 2) /* 2 less so always room for trailing \n */ - || buf_overflow (buf1, buf2, booksize)) - return 1; - - return 0; + return rbuf; } /***************************************************************************** @@ -642,100 +629,75 @@ * created and updated across multiple runs of the program. */ static void -init_book_archive (void) +init_book_archive () { - FILE *fp; - int comp, nroftitle = 0; - char buf[MAX_BUF], fname[MAX_BUF], *cp; - title *book = NULL; + int nroftitle = 0; titlelist *bl = get_empty_booklist (); - static int did_init_barch; - if (did_init_barch) - return; + object_thawer thawer (settings.localdir, "bookarch"); - did_init_barch = 1; + if (!thawer) + { + LOG (llevDebug, "could not read bookarch file\n"); + return; + } - if (!booklist) - booklist = bl; + while (thawer.kw) + { + if (thawer.kw != KW_title) + if (!thawer.parse_error ("bookarch file")) + break; - sprintf (fname, "%s/bookarch", settings.localdir); - LOG (llevDebug, " Reading bookarch from %s...\n", fname); + title *book = get_empty_book (); /* init new book entry */ + thawer.get (book->name); - if ((fp = open_and_uncompress (fname, 0, &comp)) != NULL) - { - int value, type = 0; - size_t i; + int type = -1; - while (fgets (buf, MAX_BUF, fp) != NULL) + for (;;) { - if (*buf == '#') - continue; - if ((cp = strchr (buf, '\n')) != NULL) - *cp = '\0'; - cp = buf; - while (*cp == ' ') /* Skip blanks */ - cp++; - if (!strncmp (cp, "title", 4)) - { - book = get_empty_book (); /* init new book entry */ - book->name = strchr (cp, ' ') + 1; - type = -1; - nroftitle++; - continue; - } - if (!strncmp (cp, "authour", 4)) - { - book->authour = strchr (cp, ' ') + 1; - } - if (!strncmp (cp, "arch", 4)) - { - book->archname = strchr (cp, ' ') + 1; - } - else if (sscanf (cp, "level %d", &value)) - { - book->level = (uint16) value; - } - else if (sscanf (cp, "type %d", &value)) - { - type = (uint16) value; - } - else if (sscanf (cp, "size %d", &value)) - { - book->size = (uint16) value; - } - else if (sscanf (cp, "index %d", &value)) + thawer.next (); + + switch (thawer.kw) { - book->msg_index = (uint16) value; + case KW_type: thawer.get (type ); break; + case KW_authour: thawer.get (book->authour ); break; + case KW_arch: thawer.get (book->archname ); break; + case KW_level: thawer.get (book->level ); break; + case KW_size: thawer.get (book->size ); break; + case KW_index: thawer.get (book->msg_index); break; + + case KW_end: + /* link it */ + bl = get_titlelist (type); + book->next = bl->first_book; + bl->first_book = book; + bl->number++; + ++nroftitle; + goto book_done; + + default: + delete book; + goto book_done; } - else if (!strncmp (cp, "end", 3)) - { /* link it */ - bl = get_titlelist (type); - book->next = bl->first_book; - bl->first_book = book; - bl->number++; - } - } - LOG (llevDebug, "book archives(used/avail): \n"); - for (bl = booklist, i = 0; bl != NULL && i < sizeof (max_titles) / sizeof (*max_titles); bl = bl->next, i++) - { - LOG (llevDebug, " (%d/%d)\n", bl->number, max_titles[i]); } - close_and_delete (fp, comp); + +book_done: + thawer.next (); } -#ifdef BOOK_MSG_DEBUG + LOG (llevDebug, "book archives(used/avail): \n"); + int i; + for (bl = booklist, i = 0; bl && i < sizeof (max_titles) / sizeof (*max_titles); bl = bl->next, i++) + LOG (llevDebug, " (%d/%d)\n", bl->number, max_titles[i]); + LOG (llevDebug, "init_book_archive() got %d titles.\n", nroftitle); -#endif - LOG (llevDebug, " done.\n"); } -/* init_mon_info() - creates the linked list of pointers to +/* init_mon_info() - creates the linked list of pointers to * monster archetype objects if not called previously */ - static void -init_mon_info (void) +init_mon_info () { archetype *at; static int did_init_mon_info = 0; @@ -746,29 +708,29 @@ did_init_mon_info = 1; for_all_archetypes (at) - { - if (QUERY_FLAG (at, FLAG_MONSTER) && (!QUERY_FLAG (at, FLAG_CHANGING) || QUERY_FLAG (at, FLAG_UNAGGRESSIVE))) - { - objectlink *mon = new objectlink; + if (at->flag [FLAG_MONSTER] + && at->is_head () + && (!at->flag [FLAG_CHANGING] || at->flag [FLAG_UNAGGRESSIVE])) + { + objectlink *mon = new objectlink; - mon->ob = at; - mon->next = first_mon_info; - first_mon_info = mon; - nrofmon++; - } - } + mon->ob = at; + mon->next = first_mon_info; + first_mon_info = mon; + nrofmon++; + } LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon); } -/* init_readable() - initialise linked lists utilized by - * message functions in tailor_readable_ob() +/* init_readable() - initialise linked lists utilized by + * message functions in tailor_readable_ob() * * This is the function called by the main routine to initialise * all the readable information. */ void -init_readable (void) +init_readable () { static int did_this; @@ -822,7 +784,7 @@ } /* new_text_name() - Only for objects of type BOOK. SPELLBOOK stuff is - * handled directly in change_book_name(). Names are based on text + * handled directly in change_book_name(). Names are based on text * msgtype * this sets book book->name based on msgtype given. What name * is given is based on various criteria @@ -830,8 +792,7 @@ static void new_text_name (object *book, int msgtype) { - int nbr; - char name[MAX_BUF]; + const char *name; if (book->type != BOOK) return; @@ -839,44 +800,32 @@ switch (msgtype) { case 1: /*monster */ - nbr = sizeof (mon_book_name) / sizeof (char *); - assign (name, mon_book_name[rndm (nbr)]); + name = mon_book_name[rndm (array_length (mon_book_name))]; break; case 2: /*artifact */ - nbr = sizeof (art_book_name) / sizeof (char *); - assign (name, art_book_name[rndm (nbr)]); + name = art_book_name[rndm (array_length (art_book_name))]; break; case 3: /*spellpath */ - nbr = sizeof (path_book_name) / sizeof (char *); - assign (name, path_book_name[rndm (nbr)]); + name = path_book_name[rndm (array_length (path_book_name))]; break; case 4: /*alchemy */ - nbr = sizeof (formula_book_name) / sizeof (char *); - assign (name, formula_book_name[rndm (nbr)]); + name = formula_book_name[rndm (array_length (formula_book_name))]; break; case 5: /*gods */ - nbr = sizeof (gods_book_name) / sizeof (char *); - assign (name, gods_book_name[rndm (nbr)]); + name = gods_book_name[rndm (array_length (gods_book_name))]; break; case 6: /*msg file */ default: - if (book->weight > 2000) - { /* based on weight */ - nbr = sizeof (heavy_book_name) / sizeof (char *); - assign (name, heavy_book_name[rndm (nbr)]); - } - else if (book->weight < 2001) - { - nbr = sizeof (light_book_name) / sizeof (char *); - assign (name, light_book_name[rndm (nbr)]); - } + name = book->weight > 2000 /* based on weight */ + ? heavy_book_name [rndm (array_length (heavy_book_name))] + : light_book_name [rndm (array_length (light_book_name))]; break; } book->name = name; } -/* add_book_author() +/* add_book_author() * A lot like new_text_name above, but instead chooses an author * and sets op->title to that value */ @@ -884,8 +833,7 @@ static void add_author (object *op, int msgtype) { - char title[MAX_BUF], name[MAX_BUF]; - int nbr = sizeof (book_author) / sizeof (char *); + const char *name; if (msgtype < 0 || strlen (op->msg) < 5) return; @@ -893,35 +841,29 @@ switch (msgtype) { case 1: /* monster */ - nbr = sizeof (mon_author) / sizeof (char *); - assign (name, mon_author[rndm (nbr)]); + name = mon_author[rndm (array_length (mon_author))]; break; case 2: /* artifacts */ - nbr = sizeof (art_author) / sizeof (char *); - assign (name, art_author[rndm (nbr)]); + name = art_author[rndm (array_length (art_author))]; break; case 3: /* spellpath */ - nbr = sizeof (path_author) / sizeof (char *); - assign (name, path_author[rndm (nbr)]); + name = path_author[rndm (array_length (path_author))]; break; case 4: /* alchemy */ - nbr = sizeof (formula_author) / sizeof (char *); - assign (name, formula_author[rndm (nbr)]); + name = formula_author[rndm (array_length (formula_author))]; break; case 5: /* gods */ - nbr = sizeof (gods_author) / sizeof (char *); - assign (name, gods_author[rndm (nbr)]); + name = gods_author[rndm (array_length (gods_author))]; break; case 6: /* msg file */ default: - assign (name, book_author[rndm (nbr)]); + name = book_author[rndm (array_length (book_author))]; } - sprintf (title, "of %s", name); - op->title = title; + op->title = format ("of %s", name); } -/* unique_book() - check to see if the book title/msg is unique. We +/* unique_book() - check to see if the book title/msg is unique. We * go through the entire list of possibilities each time. If we find * a match, then unique_book returns true (because inst unique). */ @@ -978,12 +920,12 @@ } -/* change_book() - give a new, fancier name to generated +/* change_book() - give a new, fancier name to generated * objects of type BOOK and SPELLBOOK. - * Aug 96 I changed this so we will attempt to create consistent + * Aug 96 I changed this so we will attempt to create consistent * authour/title and message content for BOOKs. Also, we will - * alter books that match archive entries to the archival - * levels and architypes. -b.t. + * alter books that match archive entries to the archival + * levels and architypes. -b.t. */ #define MAX_TITLE_CHECK 20 @@ -1003,14 +945,14 @@ /* look to see if our msg already been archived. If so, alter * the book to match the archival text. If we fail to match, - * then we archive the new title/name/msg combo if there is - * room on the titlelist. + * then we archive the new title/name/msg combo if there is + * room on the titlelist. */ if ((strlen (book->msg) > 5) && (t = find_title (book, msgtype))) { /* alter book properties */ - if (object *tmpbook = get_archetype (t->archname)) + if (object *tmpbook = archetype::get (t->archname)) { tmpbook->msg = book->msg; tmpbook->copy_to (book); @@ -1064,7 +1006,7 @@ * 1)If no space for a new title exists lets just restore * the old book properties. Remember, if the book had * matchd an older entry on the titlelist, we shouldnt - * have called this routine in the first place! + * have called this routine in the first place! * 2) If we got a unique title, we need to add it to * the list. */ @@ -1078,18 +1020,10 @@ book->title = old_title; if (rndm (4)) - { - /* Lets give the book a description to individualize it some */ - char new_name[MAX_BUF]; - - snprintf (new_name, MAX_BUF, "%s %s", book_descrpt[rndm (nbr)], old_name); - - book->name = new_name; - } + /* Lets give the book a description to individualize it some */ + book->name = format ("%s %s", book_descrpt[rndm (nbr)], old_name); else - { - book->name = old_name; - } + book->name = old_name; } else if (book->title && strlen (book->msg) > 5) { /* archive if long msg texts */ @@ -1116,7 +1050,7 @@ * Monster msg generation code. ****************************************************************************/ -/* get_random_mon() - returns a random monster slected from linked +/* get_random_mon() - returns a random monster slected from linked * list of all monsters in the current game. If level is non-zero, * then only monsters greater than that level will be returned. * Changed 971225 to be greater than equal to level passed. Also @@ -1152,7 +1086,7 @@ /* Case where we are searching by level. Redone 971225 to be clearer * and more random. Before, it looks like it took a random monster from * the list, and then returned the first monster after that which was - * appropriate level. This wasn't very random because if you had a + * appropriate level. This wasn't very random because if you had a * bunch of low level monsters and then a high level one, if the random * determine took one of the low level ones, it would just forward to the * high level one and return that. Thus, monsters that immediatly followed @@ -1217,6 +1151,7 @@ /* didn't find a match */ if (!mon) return NULL; + if (mon->next) return mon->next->ob; else @@ -1224,23 +1159,23 @@ } -/* mon_info_msg() - generate a message detailing the properties +/* mon_info_msg() - generate a message detailing the properties * of a randomly selected monster. */ static const char * -mon_info_msg (int level, int booksize) +mon_info_msg (int level) { static dynbuf_text buf; buf.clear (); /*preamble */ buf << "This beastiary contains:\n"; - /* lets print info on as many monsters as will fit in our - * document. + /* lets print info on as many monsters as will fit in our + * document. * 8-96 Had to change this a bit, otherwise there would * have been an impossibly large number of combinations * of text! (and flood out the available number of titles - * in the archive in a snap!) -b.t. + * in the archive in a snap!) -b.t. */ object *tmp = get_random_mon (level * 3); while (tmp && buf.size () < BOOK_BUF) @@ -1264,7 +1199,7 @@ * of 1-6 artifacts drawn sequentially from the artifact list. */ static const char * -artifact_msg (int level, int booksize) +artifact_msg (int level) { artifactlist *al = NULL; artifact *art; @@ -1288,7 +1223,7 @@ i = 0; do { - index = rndm (sizeof (art_name_array) / sizeof (arttypename)); + index = rndm (array_length (art_name_array)); type = art_name_array[index].type; al = find_artifactlist (type); i++; @@ -1318,7 +1253,7 @@ book_entries > 1 ? "some artifacts" : "an artifact"); /* artifact msg attributes loop. Lets keep adding entries to the 'book' - * as long as we have space up to the allowed max # (book_entires) + * as long as we have space up to the allowed max # (book_entires) */ while (book_entries > 0 && buf.size () < BOOK_BUF) { @@ -1371,7 +1306,7 @@ tmp = object::create (); add_abilities (tmp, art->item); tmp->type = type; - SET_FLAG (tmp, FLAG_IDENTIFIED); + tmp->set_flag (FLAG_IDENTIFIED); if ((ch = describe_item (tmp, 0)) && strlen (ch) > 1) buf << "\rProperties of this artifact include:\r" << ch << "\n"; @@ -1389,16 +1324,14 @@ *****************************************************************************/ /* spellpath_msg() - generate a message detailing the member - * incantations/prayers (and some of their properties) belonging to - * a given spellpath. + * incantations/prayers (and some of their properties) belonging to + * a given spellpath. */ static char * -spellpath_msg (int level, int booksize) +spellpath_msg (int level) { static dynbuf_text buf; buf.clear (); - static char retbuf[BOOK_BUF]; - char tmpbuf[BOOK_BUF]; int path = rndm (NRSPELLPATHS), prayers = rndm (2); uint32 pnum = (path == -1) ? PATH_NULL : spellpathdef[path]; archetype *at; @@ -1429,7 +1362,7 @@ /* Geez, no spells were generated. */ if (!seen) if (rndm (4)) /* usually, lets make a recursive call... */ - return spellpath_msg (level, booksize); + return spellpath_msg (level); else /* give up, cause knowing no spells exist for path is info too. */ buf << "- no known spells exist.\n"; @@ -1450,7 +1383,7 @@ static dynbuf_text buf; buf.clear (); /* the higher the book level, the more complex (ie number of - * ingredients) the formula can be. + * ingredients) the formula can be. */ fl = get_formulalist (rndm (level) / 3 + 1); @@ -1570,7 +1503,7 @@ * of a random god. Used by the book hack. b.t. */ static const char * -god_info_msg (int level, int booksize) +god_info_msg (int level) { const char *name = NULL; object *god = pntr_to_god_obj (get_rand_god ()); @@ -1618,8 +1551,6 @@ if (enemy && !(god->path_denied & PATH_TURNING)) if ((i = nstrtok (enemy, ",")) > 0) { - char tmpbuf[MAX_BUF]; - buf << "The holy words of " << name << " have the power to slay creatures belonging to the "; @@ -1705,7 +1636,6 @@ int has_effect = 0, tmpvar; char tmpbuf[MAX_BUF]; - sprintf (tmpbuf, "\n"); sprintf (tmpbuf, "It is rarely known fact that the priests of %s\n", name); strcat (tmpbuf, "are mystically transformed. Effects of this include:\n"); @@ -1743,15 +1673,15 @@ return buf; } -/* tailor_readable_ob()- The main routine. This chooses a random - * message to put in given readable object (type==BOOK) which will - * be referred hereafter as a 'book'. We use the book level to de- - * termine the value of the information we will insert. Higher - * values mean the book will (generally) have better/more info. +/* tailor_readable_ob()- The main routine. This chooses a random + * message to put in given readable object (type==BOOK) which will + * be referred hereafter as a 'book'. We use the book level to de- + * termine the value of the information we will insert. Higher + * values mean the book will (generally) have better/more info. * See individual cases as to how this will be utilized. - * "Book" name/content length are based on the weight of the + * "Book" name/content length are based on the weight of the * document. If the value of msg_type is negative, we will randomly - * choose the kind of message to generate. + * choose the kind of message to generate. * -b.t. thomas@astro.psu.edu * * book is the object we are creating into. @@ -1762,9 +1692,7 @@ void tailor_readable_ob (object *book, int msg_type) { - char msgbuf[BOOK_BUF]; int level = book->level ? rndm (book->level) + 1 : 1; - int book_buf_size; /* safety */ if (book->type != BOOK) @@ -1773,9 +1701,6 @@ if (level <= 0) return; /* if no level no point in doing any more... */ - /* Max text length this book can have. */ - book_buf_size = BOOKSIZE (book); - /* &&& The message switch &&& */ /* Below all of the possible types of messages in the "book"s. */ @@ -1787,24 +1712,25 @@ * and add_authour(). * 4) you may want separate authour/book name arrays in read.h */ + const char *new_msg = ""; msg_type = msg_type > 0 ? msg_type : rndm (8); switch (msg_type) { case 1: /* monster attrib */ - strcpy (msgbuf, mon_info_msg (level, book_buf_size)); + new_msg = mon_info_msg (level); break; case 2: /* artifact attrib */ - strcpy (msgbuf, artifact_msg (level, book_buf_size)); + new_msg = artifact_msg (level); break; case 3: /* grouping incantations/prayers by path */ - strcpy (msgbuf, spellpath_msg (level, book_buf_size)); + new_msg = spellpath_msg (level); break; case 4: /* describe an alchemy formula */ make_formula_book (book, level); /* make_formula_book already gives title */ return; case 5: /* bits of information about a god */ - strcpy (msgbuf, god_info_msg (level, book_buf_size)); + new_msg = god_info_msg (level); break; case 0: /* use info list in lib/ */ default: @@ -1813,68 +1739,22 @@ return; } - if (strlen (msgbuf) > 1) + if (strlen (new_msg) > 1) { - book->msg = msgbuf; + book->msg = new_msg; /* lets give the "book" a new name, which may be a compound word */ change_book (book, msg_type); } } - -/***************************************************************************** - * - * Cleanup routine for readble stuff. - * - *****************************************************************************/ - -void -free_all_readable (void) -{ - titlelist *tlist, *tnext; - title *title1, *titlenext; - linked_char *lmsg, *nextmsg; - objectlink *monlink, *nextmon; - - LOG (llevDebug, "freeing all book information\n"); - - for (tlist = booklist; tlist; tlist = tnext) - { - tnext = tlist->next; - - for (title1 = tlist->first_book; title1; title1 = titlenext) - { - titlenext = title1->next; - delete title1; - } - - delete tlist; - } - - for (lmsg = first_msg; lmsg; lmsg = nextmsg) - { - nextmsg = lmsg->next; - delete lmsg; - } - - for (monlink = first_mon_info; monlink; monlink = nextmon) - { - nextmon = monlink->next; - delete monlink; - } -} - - /***************************************************************************** * * Writeback routine for updating the bookarchive. * ****************************************************************************/ - /* write_book_archive() - write out the updated book archive */ - void -write_book_archive (void) +write_book_archive () { FILE *fp; int index = 0; @@ -1885,15 +1765,14 @@ /* If nothing changed, don't write anything */ if (!need_to_write_bookarchive) return; + need_to_write_bookarchive = 0; sprintf (fname, "%s/bookarch", settings.localdir); LOG (llevDebug, "Updating book archive: %s...\n", fname); if ((fp = fopen (fname, "w")) == NULL) - { - LOG (llevDebug, "Can't open book archive file %s\n", fname); - } + LOG (llevDebug, "Can't open book archive file %s\n", fname); else { while (bl) @@ -1910,13 +1789,16 @@ fprintf (fp, "index %d\n", book->msg_index); fprintf (fp, "end\n"); } + bl = bl->next; index++; } + fclose (fp); chmod (fname, SAVE_MODE); } } + readable_message_type * get_readable_message_type (object *readable) {