--- deliantra/server/common/readable.C 2008/12/27 02:31:19 1.38 +++ deliantra/server/common/readable.C 2009/10/16 00:02:22 1.49 @@ -1,22 +1,23 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * 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 * - * Deliantra is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * 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 GNU General Public License - * along with this program. If not, see . + * 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 */ @@ -32,7 +33,6 @@ #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. @@ -571,8 +571,7 @@ /* nstrtok() - simple routine to return the number of list * items in buf1 as separated by the value of buf2 */ - -int +static int nstrtok (const char *buf1, const char *buf2) { char *tbuf, sbuf[12], buf[MAX_BUF]; @@ -595,8 +594,7 @@ * a list of strings delimited by buf2. Then returns a comma * separated string w/ decent punctuation. */ - -char * +static char * strtoktolin (const char *buf1, const char *buf2) { int maxi, i = nstrtok (buf1, buf2); @@ -623,16 +621,14 @@ return (char *) rbuf; } -int +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 0; } /***************************************************************************** @@ -737,9 +733,8 @@ /* 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; @@ -750,17 +745,17 @@ 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; - - mon->ob = at; - mon->next = first_mon_info; - first_mon_info = mon; - nrofmon++; - } - } + 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++; + } LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon); } @@ -819,7 +814,7 @@ #ifdef ARCHIVE_DEBUG if (t) - LOG (llevDebug, "Found title match (list %d): %s %s (%d)\n", msgtype, t->name, t->authour, t->msg_index); + LOG (llevDebug, "Found title match (list %d): %s %s (%d)\n", msgtype, &t->name, &t->authour, t->msg_index); #endif return t; @@ -831,7 +826,6 @@ * this sets book book->name based on msgtype given. What name * is given is based on various criteria */ - static void new_text_name (object *book, int msgtype) { @@ -934,19 +928,16 @@ static int unique_book (const object *book, int msgtype) { - title *test; - if (!booklist) return 1; /* No archival entries! Must be unique! */ /* Go through the booklist. If the author and name match, not unique so * return 0. */ - for (test = get_titlelist (msgtype)->first_book; test; test = test->next) - { - if (!strcmp (test->name, book->name) && !strcmp (book->title, test->authour)) - return 0; - } + for (title *test = get_titlelist (msgtype)->first_book; test; test = test->next) + if (test->name == book->name && book->title == test->authour) + return 0; + return 1; } @@ -980,7 +971,7 @@ need_to_write_bookarchive = 1; #ifdef ARCHIVE_DEBUG - LOG (llevDebug, "Archiving new title: %s %s (%d)\n", book->name, book->title, msgtype); + LOG (llevDebug, "Archiving new title: %s %s (%d)\n", &book->name, &book->title, msgtype); #endif } @@ -996,7 +987,7 @@ #define MAX_TITLE_CHECK 20 -void +static void change_book (object *book, int msgtype) { int nbr = sizeof (book_descrpt) / sizeof (char *); @@ -1056,7 +1047,6 @@ #ifdef ARCHIVE_DEBUG LOG (llevDebug, "titles for list %d full (%d possible).\n", msgtype, maxnames); #endif - break; } /* shouldnt change map-maker books */ else if (!book->title) @@ -1081,7 +1071,7 @@ if (tries == MAX_TITLE_CHECK || numb == maxnames) { /* got to check maxnames again */ #ifdef ARCHIVE_DEBUG - LOG (llevDebug, "Failed to obtain unique title for %s %s (names:%d/%d)\n", book->name, book->title, numb, maxnames); + LOG (llevDebug, "Failed to obtain unique title for %s %s (names:%d/%d)\n", &book->name, &book->title, numb, maxnames); #endif /* restore old book properties here */ book->title = old_title; @@ -1131,7 +1121,6 @@ * Changed 971225 to be greater than equal to level passed. Also * made choosing by level more random. */ - object * get_random_mon (int level) { @@ -1199,16 +1188,15 @@ * Returns a description of the monster. This really needs to be * redone, as describe_item really gives a pretty internal description. */ - -char * +static const char * mon_desc (const object *mon) { - static char retbuf[HUGE_BUF]; + static dynbuf_text buf; buf.clear (); - sprintf (retbuf, " *** %s ***\n", &mon->name); - strcat (retbuf, describe_item (mon, NULL)); + buf.printf ("B<< %s >>\r", &mon->name); + buf << describe_item (mon, 0); - return retbuf; + return buf; } @@ -1216,8 +1204,7 @@ * found, it returns NULL (changed 0.94.3 to do this, since the * calling function (mon_info_msg) seems to expect that. */ - -object * +static object * get_next_mon (object *tmp) { objectlink *mon; @@ -1229,6 +1216,7 @@ /* didn't find a match */ if (!mon) return NULL; + if (mon->next) return mon->next->ob; else @@ -1236,21 +1224,16 @@ } - - /* mon_info_msg() - generate a message detailing the properties * of a randomly selected monster. */ - -char * +static const char * mon_info_msg (int level, int booksize) { - static char retbuf[BOOK_BUF]; - char tmpbuf[HUGE_BUF]; - object *tmp; + static dynbuf_text buf; buf.clear (); /*preamble */ - strcpy (retbuf, "This beastiary contains:"); + buf << "This beastiary contains:\n"; /* lets print info on as many monsters as will fit in our * document. @@ -1259,27 +1242,17 @@ * of text! (and flood out the available number of titles * in the archive in a snap!) -b.t. */ - tmp = get_random_mon (level * 3); - while (tmp) + object *tmp = get_random_mon (level * 3); + while (tmp && buf.size () < BOOK_BUF) { /* monster description */ - sprintf (tmpbuf, "\n---\n%s", mon_desc (tmp)); - - if (!book_overflow (retbuf, tmpbuf, booksize)) - strcat (retbuf, tmpbuf); - else - break; + buf.printf ("\n%s\n", mon_desc (tmp)); /* Note that the value this returns is not based on level */ tmp = get_next_mon (tmp); } -#ifdef BOOK_MSG_DEBUG - LOG (llevDebug, "\n mon_info_msg() created strng: %d\n", strlen (retbuf)); - fprintf (logfile, " MADE THIS:\n%s\n", retbuf); -#endif - - return retbuf; + return buf; } @@ -1290,7 +1263,7 @@ /* artifact_msg() - generate a message detailing the properties * of 1-6 artifacts drawn sequentially from the artifact list. */ -const char * +static const char * artifact_msg (int level, int booksize) { artifactlist *al = NULL; @@ -1298,10 +1271,11 @@ int chance, i, type, index; int book_entries = level > 5 ? rndm (3) + rndm (3) + 2 : rndm (level) + 1; const char *ch; - char name[MAX_BUF], buf[BOOK_BUF], sbuf[MAX_BUF]; - static char retbuf[BOOK_BUF]; + char name[MAX_BUF]; object *tmp = NULL; + static dynbuf_text buf; buf.clear (); + /* values greater than 5 create msg buffers that are too big! */ if (book_entries > 5) book_entries = 5; @@ -1339,22 +1313,23 @@ assign (name, art_name_array[index].name); /* Ok, lets print out the contents */ - sprintf (retbuf, "Herein %s detailed %s...\n", book_entries > 1 ? "are" : "is", book_entries > 1 ? "some artifacts" : "an artifact"); + buf.printf ("Herein %s detailed %s...\n", + book_entries > 1 ? "are" : "is", + 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) */ - while (book_entries > 0) + while (book_entries > 0 && buf.size () < BOOK_BUF) { - if (art == NULL) + if (!art) art = al->items; - /* separator of items */ - strcpy (buf, "--- \n"); + buf << '\n'; /* Name */ - if (art->allowed != NULL && strcmp (art->allowed->name, "All")) + if (art->allowed && art->allowed->name != shstr_All) { linked_char *temp, *next = art->allowed; @@ -1364,56 +1339,49 @@ next = next->next; } while (next && rndm (2)); - sprintf (buf, "%s A %s of %s", buf, &temp->name, &art->item->name); + + buf.printf ("A B<< %s of %s >>", &temp->name, &art->item->name); } else /* default name is used */ - sprintf (buf, "%s The %s of %s", buf, name, &art->item->name); + buf.printf ("The B<< %s of %s >>", name, &art->item->name); + + buf << " is "; /* chance of finding */ chance = (int) (100 * ((float) art->chance / al->total_chance)); if (chance >= 20) - sprintf (sbuf, "an uncommon"); + buf << "an uncommon"; else if (chance >= 10) - sprintf (sbuf, "an unusual"); + buf << "an unusual"; else if (chance >= 5) - sprintf (sbuf, "a rare"); + buf << "a rare"; else - sprintf (sbuf, "a very rare"); - sprintf (buf, "%s is %s\n", buf, sbuf); + buf << "a very rare"; /* value of artifact */ - sprintf (buf, "%s item with a value that is %d times normal.\n", buf, art->item->value); + buf << " item with a value that is " << art->item->value << " times normal.\n"; /* include the message about the artifact, if exists, and book * level is kinda high */ if (art->item->msg - && rndm (4) + 1 < level - && !(strlen (art->item->msg) + strlen (buf) > BOOK_BUF)) - strcat (buf, art->item->msg); + && rndm (4) + 1 < level) + buf << art->item->msg; /* properties of the artifact */ tmp = object::create (); add_abilities (tmp, art->item); tmp->type = type; SET_FLAG (tmp, FLAG_IDENTIFIED); - if ((ch = describe_item (tmp, NULL)) != NULL && strlen (ch) > 1) - sprintf (buf, "%s Properties of this artifact include: \n %s \n", buf, ch); + if ((ch = describe_item (tmp, 0)) && strlen (ch) > 1) + buf << "\rProperties of this artifact include:\r" << ch << "\n"; + tmp->destroy (); - /* add the buf if it will fit */ - if (!book_overflow (retbuf, buf, booksize)) - strcat (retbuf, buf); - else - break; art = art->next; book_entries--; } -#ifdef BOOK_MSG_DEBUG - LOG (llevDebug, "artifact_msg() created strng: %d\n", strlen (retbuf)); - fprintf (logfile, " MADE THIS:\n%s", retbuf); -#endif - return retbuf; + return buf; } /***************************************************************************** @@ -1424,73 +1392,63 @@ * incantations/prayers (and some of their properties) belonging to * a given spellpath. */ - -char * +static char * spellpath_msg (int level, int booksize) { + static dynbuf_text buf; buf.clear (); + static char retbuf[BOOK_BUF]; char tmpbuf[BOOK_BUF]; int path = rndm (NRSPELLPATHS), prayers = rndm (2); - int did_first_sp = 0; uint32 pnum = (path == -1) ? PATH_NULL : spellpathdef[path]; archetype *at; /* Preamble */ - sprintf (retbuf, "Herein are detailed the names of %s\n", prayers ? "prayers" : "incantations"); + buf << "Herein are detailed the names of " + << (prayers ? "prayers" : "incantations"); if (path == -1) - strcat (retbuf, "having no known spell path.\n"); + buf << " having no known spell path.\n"; else - sprintf (retbuf, "%sbelonging to the path of %s:\n", retbuf, spellpathnames[path]); + buf << " belonging to the path of B<< " << spellpathnames[path] << " >>:\n\n"; + + int seen = 0; for_all_archetypes (at) - { - /* Determine if this is an appropriate spell. Must - * be of matching path, must be of appropriate type (prayer - * or not), and must be within the valid level range. - */ - if (at->type == SPELL && at->path_attuned & pnum && - ((at->stats.grace && prayers) || (at->stats.sp && !prayers)) && (at->level < (level * 8))) - { - assign (tmpbuf, at->object::name); + /* Determine if this is an appropriate spell. Must + * be of matching path, must be of appropriate type (prayer + * or not), and must be within the valid level range. + */ + if (at->type == SPELL && at->path_attuned & pnum && + ((at->stats.grace && prayers) || (at->stats.sp && !prayers)) && (at->level < (level * 8))) + { + seen = 1; + buf << at->object::name << '\r'; + } - if (book_overflow (retbuf, tmpbuf, booksize)) - break; - else - { - if (did_first_sp) - strcat (retbuf, ",\n"); - did_first_sp = 1; - strcat (retbuf, tmpbuf); - } - } - } /* Geez, no spells were generated. */ - if (!did_first_sp) - { - if (rndm (4)) /* usually, lets make a recursive call... */ - spellpath_msg (level, booksize); - else /* give up, cause knowing no spells exist for path is info too. */ - strcat (retbuf, "\n - no known spells exist -\n"); - } - else - { - strcat (retbuf, "\n"); - } - return retbuf; + if (!seen) + if (rndm (4)) /* usually, lets make a recursive call... */ + return spellpath_msg (level, booksize); + else /* give up, cause knowing no spells exist for path is info too. */ + buf << "- no known spells exist.\n"; + + return buf; } /* formula_msg() - generate a message detailing the properties * of a randomly selected alchemical formula. */ -void +static void make_formula_book (object *book, int level) { - char retbuf[BOOK_BUF], title[MAX_BUF]; + char title[MAX_BUF]; recipelist *fl; recipe *formula = NULL; int chance; + static dynbuf_text buf; buf.clear (); + /* the higher the book level, the more complex (ie number of * ingredients) the formula can be. */ @@ -1512,6 +1470,7 @@ for (formula = fl->items; formula; formula = formula->next) { chance -= formula->chance; + if (chance <= 0) break; } @@ -1521,77 +1480,75 @@ book->msg = "\n"; new_text_name (book, 4); add_author (book, 4); - + return; } - else - { - /* looks like a formula was found. Base the amount - * of information on the booklevel and the spellevel - * of the formula. */ - const char *op_name = formula->arch_name [rndm (formula->arch_names)]; - archetype *at; + /* looks like a formula was found. Base the amount + * of information on the booklevel and the spellevel + * of the formula. */ - /* preamble */ - sprintf (retbuf, "Herein is described a project using %s: \n", formula->skill ? &formula->skill : "an unknown skill"); + const char *op_name = formula->arch_name [rndm (formula->arch_names)]; + archetype *at; - if ((at = archetype::find (op_name)) != (archetype *) NULL) - op_name = at->object::name; - else - LOG (llevError, "formula_msg() can't find arch %s for formula.\n", op_name); + /* preamble */ + buf << "Herein is described a project using B<< " + << (formula->skill ? &formula->skill : "an unknown skill") + << " >>:\n\n"; - /* item name */ - if (strcmp (formula->title, "NONE")) - { - sprintf (retbuf, "%sThe %s of %s", retbuf, op_name, &formula->title); - /* This results in things like pile of philo. sulfur. - * while philo. sulfur may look better, without this, - * you get things like 'the wise' because its missing the - * water of section. - */ - sprintf (title, "%s: %s of %s", - formula_book_name [rndm (sizeof (formula_book_name) / sizeof (char *))], op_name, &formula->title); - } - else + if ((at = archetype::find (op_name))) + op_name = at->object::name; + else + LOG (llevError, "formula_msg() can't find arch %s for formula.\n", op_name); + + /* item name */ + if (formula->title != shstr_NONE) + { + buf.printf ("The B<< %s of %s >>", op_name, &formula->title); + /* This results in things like pile of philo. sulfur. + * while philo. sulfur may look better, without this, + * you get things like 'the wise' because its missing the + * water of section. + */ + sprintf (title, "%s: %s of %s", + formula_book_name [rndm (sizeof (formula_book_name) / sizeof (char *))], op_name, &formula->title); + } + else + { + buf << "The B<< " << op_name; + + sprintf (title, "%s: %s", formula_book_name [rndm (sizeof (formula_book_name) / sizeof (char *))], op_name); + if (at->title) { - sprintf (retbuf, "%sThe %s", retbuf, op_name); - sprintf (title, "%s: %s", formula_book_name [rndm (sizeof (formula_book_name) / sizeof (char *))], op_name); - if (at->title) - { - strcat (retbuf, " "); - strcat (retbuf, at->title); - strcat (title, " "); - strcat (title, at->title); - } + buf << " " << at->title; + strcat (title, " "); + strcat (title, at->title); } - /* Lets name the book something meaningful ! */ - book->name = title; - book->title = NULL; - /* ingredients to make it */ - if (formula->ingred != NULL) - { - linked_char *next; - archetype *at; + buf << " >>"; + } - at = archetype::find (formula->cauldron); + /* Lets name the book something meaningful ! */ + book->name = title; + book->title = NULL; - sprintf (retbuf + strlen (retbuf), - " may be made at %s using the following ingredients:\n", at ? query_name (at) : "an unknown place"); + /* ingredients to make it */ + if (formula->ingred) + { + linked_char *next; + archetype *at; - for (next = formula->ingred; next != NULL; next = next->next) - { - strcat (retbuf, next->name); - strcat (retbuf, "\n"); - } - } - else - LOG (llevError, "formula_msg() no ingredient list for object %s of %s\n", op_name, &formula->title); - if (retbuf[strlen (retbuf) - 1] != '\n') - strcat (retbuf, "\n"); + at = archetype::find (formula->cauldron); - book->msg = retbuf; + buf.printf (" may be made at %s using the following ingredients:\n\n", + at ? query_name (at) : "an appropriate place"); + + for (next = formula->ingred; next; next = next->next) + buf << next->name << '\r'; } + else + LOG (llevError, "formula_msg() no ingredient list for object %s of %s\n", op_name, &formula->title); + + book->msg = buf; } #define DESCRIBE_PATH(retbuf, variable, name) \ @@ -1612,151 +1569,139 @@ /* god_info_msg() - generate a message detailing the properties * of a random god. Used by the book hack. b.t. */ -const char * +static const char * god_info_msg (int level, int booksize) { - static char retbuf[BOOK_BUF]; const char *name = NULL; - char buf[BOOK_BUF]; - int i; - size_t introlen; object *god = pntr_to_god_obj (get_rand_god ()); + static dynbuf_text buf; buf.clear (); + if (!god) - return (char *) NULL; /* oops, problems... */ + return 0; /* oops, problems... */ + name = god->name; /* preamble.. */ - sprintf (retbuf, "This document contains knowledge concerning\n"); - sprintf (retbuf, "%sthe diety %s", retbuf, name); + buf << "This document contains knowledge concerning the diety B<< " + << name << " >>"; /* Always have as default information the god's descriptive terms. */ if (nstrtok (god->msg, ",") > 0) - { - strcat (retbuf, ", known as"); - strcat (retbuf, strtoktolin (god->msg, ",")); - } + buf << ", known as" << strtoktolin (god->msg, ","); else - strcat (retbuf, "..."); + buf << "..."; + + buf << "\n\n"; - strcat (retbuf, "\n ---\n"); - introlen = strlen (retbuf); /* so we will know if no new info is added later */ + int introlen = buf.size (); /* so we will know if no new info is added later */ /* Information about the god is random, and based on the level of the * 'book'. Probably there is a more intellegent way to implement * this ... */ - while (level > 0) + while (level > 0 && buf.size () < BOOK_BUF) { - sprintf (buf, " "); if (level == 2 && rndm (2)) { /* enemy god */ const char *enemy = god->title; if (enemy) - sprintf (buf, "The gods %s and %s are enemies.\n ---\n", name, enemy); + buf.printf ("The gods %s and %s are enemies.\r", name, enemy); } if (level == 3 && rndm (2)) { /* enemy race, what the god's holy word effects */ const char *enemy = god->slaying; + int i; if (enemy && !(god->path_denied & PATH_TURNING)) if ((i = nstrtok (enemy, ",")) > 0) { char tmpbuf[MAX_BUF]; - sprintf (buf, "The holy words of %s have the power to\n", name); - strcat (buf, "slay creatures belonging to the "); + buf << "The holy words of " << name + << " have the power to slay creatures belonging to the "; + if (i > 1) - sprintf (tmpbuf, "following \n races:%s", strtoktolin (enemy, ",")); + buf << "following races:" << strtoktolin (enemy, ","); else - sprintf (tmpbuf, "race of%s", strtoktolin (enemy, ",")); - sprintf (buf, "%s%s\n ---\n", buf, tmpbuf); + buf << "race of" << strtoktolin (enemy, ","); + + buf << '\r'; } } if (level == 4 && rndm (2)) { /* Priest of god gets these protect,vulnerable... */ - char tmpbuf[MAX_BUF]; - if (const char *cp = describe_resistance (god, 1)) { /* This god does have protections */ - sprintf (tmpbuf, "%s has a potent aura which is extended\n", name); - strcat (tmpbuf, "faithful priests. The effects of this aura include:\n"); - strcat (tmpbuf, cp); - strcat (buf, tmpbuf); - strcat (buf, "\n ---\n"); + buf << name + << " has a potent aura which is extended to" + " faithful priests. The effects of this aura include: " + << cp + << ".\r"; } - else - sprintf (buf, " "); } if (level == 5 && rndm (2)) { /* aligned race, summoning */ const char *race = god->race; /* aligned race */ + int i; if (race && !(god->path_denied & PATH_SUMMON)) if ((i = nstrtok (race, ",")) > 0) { - char tmpbuf[MAX_BUF]; - - sprintf (buf, "Creatures sacred to %s include the \n", name); + buf << "Creatures sacred to " << name << " include the "; if (i > 1) - sprintf (tmpbuf, "following \n races:%s", strtoktolin (race, ",")); + buf << "following races:" << strtoktolin (race, ","); else - sprintf (tmpbuf, "race of%s", strtoktolin (race, ",")); - sprintf (buf, "%s%s\n ---\n", buf, tmpbuf); + buf << "race of" << strtoktolin (race, ","); + + buf << '\r'; } } if (level == 6 && rndm (2)) { /* blessing,curse properties of the god */ - char tmpbuf[MAX_BUF]; - if (const char *cp = describe_resistance (god, 1)) { /* This god does have protections */ - sprintf (tmpbuf, "\nThe priests of %s are known to be able to \n", name); - strcat (tmpbuf, "bestow a blessing which makes the recipient\n"); - strcat (tmpbuf, cp); - strcat (buf, tmpbuf); - strcat (buf, "\n ---\n"); + buf << "The priests of " << name + << " are known to be able to " + "bestow a blessing which makes the recipient " + << cp + << '\r'; } - else - sprintf (buf, " "); - } if (level == 8 && rndm (2)) { /* immunity, holy possession */ - int has_effect = 0, tmpvar; - char tmpbuf[MAX_BUF]; - - sprintf (tmpbuf, "\n"); - sprintf (tmpbuf, "The priests of %s are known to make cast a mighty \n", name); + buf << "The priests of " << name + << " are known to make cast a mighty" + " prayer of possession"; + + int first = 1; - strcat (tmpbuf, "prayer of possession which gives the recipient\n"); + for (int i = 0; i < NROFATTACKS; i++) + if (god->resist[i] == 100) + { + if (first) + { + buf << " which gives the recipient"; + first = 0; + } + else + buf << ", "; - for (tmpvar = 0; tmpvar < NROFATTACKS; tmpvar++) - { - if (god->resist[tmpvar] == 100) - { - has_effect = 1; - sprintf (tmpbuf + strlen (tmpbuf), "Immunity to %s", attacktype_desc[tmpvar]); - } + buf << " immunity to " << attacktype_desc[i]; } - if (has_effect) - { - strcat (buf, tmpbuf); - strcat (buf, "\n ---\n"); - } - else - sprintf (buf, " "); + buf << ".\r"; } if (level == 12 && rndm (2)) { /* spell paths */ + //TODO: int has_effect = 0, tmpvar; char tmpbuf[MAX_BUF]; @@ -1783,36 +1728,19 @@ } if (has_effect) - { - strcat (buf, tmpbuf); - strcat (buf, "\n ---\n"); - } + buf << tmpbuf << '\r'; else - sprintf (buf, " "); + buf << '\r'; } - /* check to be sure new buffer size dont exceed either - * the maximum buffer size, or the 'natural' size of the - * book... - */ - if (book_overflow (retbuf, buf, booksize)) - break; - else if (strlen (buf) > 1) - strcat (retbuf, buf); - level--; } - if (strlen (retbuf) == introlen) - { /* we got no information beyond the preamble! */ - strcat (retbuf, " [Unfortunately the rest of the information is\n"); - strcat (retbuf, " hopelessly garbled!]\n ---\n"); - } -#ifdef BOOK_MSG_DEBUG - LOG (llevDebug, "\n god_info_msg() created strng: %d\n", strlen (retbuf)); - fprintf (logfile, " MADE THIS:\n%s", retbuf); -#endif - return retbuf; + if (buf.size () == introlen) + /* we got no information beyond the preamble! */ + buf << "[Unfortunately the rest of the information is hopelessly garbled!]"; + + return buf; } /* tailor_readable_ob()- The main routine. This chooses a random @@ -1875,18 +1803,16 @@ make_formula_book (book, level); /* make_formula_book already gives title */ return; - break; case 5: /* bits of information about a god */ strcpy (msgbuf, god_info_msg (level, book_buf_size)); break; case 0: /* use info list in lib/ */ default: cfperl_make_book (book, level); + /* already gives title */ return; } - strcat (msgbuf, "\n"); /* safety -- we get ugly map saves/crashes w/o this */ - if (strlen (msgbuf) > 1) { book->msg = msgbuf; @@ -1912,7 +1838,7 @@ LOG (llevDebug, "freeing all book information\n"); - for (tlist = booklist; tlist != NULL; tlist = tnext) + for (tlist = booklist; tlist; tlist = tnext) { tnext = tlist->next;