--- deliantra/server/common/readable.C 2006/09/10 16:00:23 1.5 +++ deliantra/server/common/readable.C 2007/05/17 21:32:08 1.23 @@ -1,32 +1,27 @@ - /* - * static char *rcsid_readable_c = - * "$Id: readable.C,v 1.5 2006/09/10 16:00:23 root Exp $"; + * CrossFire, A Multiplayer game + * + * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team + * Copyright (C) 2002 Mark Wedel & Crossfire Development Team + * Copyright (C) 1992 Frank Tore Johansen + * + * This program 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * The authors can be reached via e-mail at */ -/* - CrossFire, A Multiplayer game for X-windows - - Copyright (C) 2002 Mark Wedel & Crossfire Development Team - Copyright (C) 1992 Frank Tore Johansen - - This program 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 2 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - The authors can be reached via e-mail at crossfire-devel@real-time.com -*/ - /* This file contains code relevant to the BOOKS hack -- designed * to allow randomly occuring messages in non-magical texts. @@ -82,7 +77,7 @@ */ /* 'title' and 'titlelist' are used by the readable code */ -typedef struct titlestruct:zero_initialised +struct title : zero_initialised { shstr name; /* the name of the book */ shstr authour; /* the name of the book authour */ @@ -90,25 +85,22 @@ int level; /* level of difficulty of this message */ int size; /* size of the book message */ int msg_index; /* an index value derived from book message */ - struct titlestruct *next; -} title; + title *next; +}; -typedef struct titleliststruct:zero_initialised +struct titlelist : zero_initialised { int number; /* number of items in the list */ - struct titlestruct *first_book; /* pointer to first book in this list */ - struct titleliststruct *next; /* pointer to next book list */ -} titlelist; + title *first_book; /* pointer to first book in this list */ + titlelist *next; /* pointer to next book list */ +}; /* special structure, used only by art_name_array[] */ - -typedef struct namebytype +struct arttypename { const char *name; /* generic name to call artifacts of this type */ int type; /* matching type */ -} -arttypename; - +}; /* booklist is the buffer of books read in from the bookarch file */ static titlelist *booklist = NULL; @@ -121,7 +113,7 @@ static int nrofmon = 0, need_to_write_bookarchive = 0; -/* this is needed to keep track of status of initialization +/* this is needed to keep track of status of initialisation * of the message file */ static int nrofmsg = 0; @@ -198,7 +190,7 @@ {"Boots", BOOTS}, {"Cloak", CLOAK}, {"Gloves", GLOVES}, - {"Gridle", GIRDLE}, + {"Girdle", GIRDLE}, {"Ring", RING}, {"Horn", HORN}, {"Missile Weapon", BOW}, @@ -567,6 +559,7 @@ { if (!tl->next) tl->next = get_empty_booklist (); + tl = tl->next; number--; } @@ -646,11 +639,11 @@ /***************************************************************************** * - * Start of initialization related functions. + * Start of initialisation related functions. * ****************************************************************************/ -/* init_msgfile() - if not called before, initialize the info list +/* init_msgfile() - if not called before, initialise the info list * reads the messages file into the list pointed to by first_msg */ @@ -667,7 +660,7 @@ did_init_msgfile = 1; sprintf (fname, "%s/messages", settings.datadir); - LOG (llevDebug, "Reading messages from %s...", fname); + LOG (llevDebug, "Reading messages from %s...\n", fname); if ((fp = open_and_uncompress (fname, 0, &comp)) != NULL) { @@ -687,7 +680,7 @@ if (strlen (msgbuf) > BOOK_BUF) { LOG (llevDebug, "Warning: this string exceeded max book buf size:"); - LOG (llevDebug, " %s", msgbuf); + LOG (llevDebug, " %s\n", msgbuf); } tmp->name = msgbuf; tmp->next = first_msg; @@ -712,13 +705,13 @@ } #ifdef BOOK_MSG_DEBUG - LOG (llevDebug, "\ninit_info_listfile() got %d messages.\n", nrofmsg); + LOG (llevDebug, "init_info_listfile() got %d messages.\n", nrofmsg); #endif LOG (llevDebug, "done.\n"); } -/* init_book_archive() - if not called before, initialize the info list +/* init_book_archive() - if not called before, initialise the info list * This reads in the bookarch file into memory. bookarch is the file * created and updated across multiple runs of the program. */ @@ -735,6 +728,7 @@ if (did_init_barch) return; + did_init_barch = 1; if (!booklist) @@ -797,17 +791,16 @@ bl->number++; } } - LOG (llevDebug, " book archives(used/avail): "); + 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)", bl->number, max_titles[i]); + LOG (llevDebug, " (%d/%d)\n", bl->number, max_titles[i]); } - LOG (llevDebug, "\n"); close_and_delete (fp, comp); } #ifdef BOOK_MSG_DEBUG - LOG (llevDebug, "\n init_book_archive() got %d titles.\n", nroftitle); + LOG (llevDebug, "init_book_archive() got %d titles.\n", nroftitle); #endif LOG (llevDebug, " done.\n"); } @@ -824,6 +817,7 @@ if (did_init_mon_info) return; + did_init_mon_info = 1; @@ -831,23 +825,23 @@ { if (QUERY_FLAG (&at->clone, FLAG_MONSTER) && (!QUERY_FLAG (&at->clone, FLAG_CHANGING) || QUERY_FLAG (&at->clone, FLAG_UNAGGRESSIVE))) { - objectlink *mon = (objectlink *) malloc (sizeof (objectlink)); + objectlink *mon = new objectlink; mon->ob = &at->clone; - mon->id = nrofmon; mon->next = first_mon_info; first_mon_info = mon; nrofmon++; } } + LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon); } -/* init_readable() - initialize linked lists utilized by +/* init_readable() - initialise linked lists utilized by * message functions in tailor_readable_ob() * - * This is the function called by the main routine to initialize + * This is the function called by the main routine to initialise * all the readable information. */ @@ -858,9 +852,10 @@ if (did_this) return; + did_this = 1; - LOG (llevDebug, "Initializing reading data..."); + LOG (llevDebug, "Initialising reading data...\n"); init_msgfile (); init_book_archive (); init_mon_info (); @@ -893,6 +888,7 @@ if (tl) t = tl->first_book; + while (t) if (t->size == length && t->msg_index == index) break; @@ -925,39 +921,39 @@ switch (msgtype) { - case 1: /*monster */ - nbr = sizeof (mon_book_name) / sizeof (char *); - strcpy (name, mon_book_name[RANDOM () % nbr]); - break; - case 2: /*artifact */ - nbr = sizeof (art_book_name) / sizeof (char *); - strcpy (name, art_book_name[RANDOM () % nbr]); - break; - case 3: /*spellpath */ - nbr = sizeof (path_book_name) / sizeof (char *); - strcpy (name, path_book_name[RANDOM () % nbr]); - break; - case 4: /*alchemy */ - nbr = sizeof (formula_book_name) / sizeof (char *); - strcpy (name, formula_book_name[RANDOM () % nbr]); - break; - case 5: /*gods */ - nbr = sizeof (gods_book_name) / sizeof (char *); - strcpy (name, gods_book_name[RANDOM () % nbr]); - break; - case 6: /*msg file */ - default: - if (book->weight > 2000) - { /* based on weight */ - nbr = sizeof (heavy_book_name) / sizeof (char *); - strcpy (name, heavy_book_name[RANDOM () % nbr]); - } - else if (book->weight < 2001) - { - nbr = sizeof (light_book_name) / sizeof (char *); - strcpy (name, light_book_name[RANDOM () % nbr]); - } - break; + case 1: /*monster */ + nbr = sizeof (mon_book_name) / sizeof (char *); + assign (name, mon_book_name[rndm (nbr)]); + break; + case 2: /*artifact */ + nbr = sizeof (art_book_name) / sizeof (char *); + assign (name, art_book_name[rndm (nbr)]); + break; + case 3: /*spellpath */ + nbr = sizeof (path_book_name) / sizeof (char *); + assign (name, path_book_name[rndm (nbr)]); + break; + case 4: /*alchemy */ + nbr = sizeof (formula_book_name) / sizeof (char *); + assign (name, formula_book_name[rndm (nbr)]); + break; + case 5: /*gods */ + nbr = sizeof (gods_book_name) / sizeof (char *); + assign (name, gods_book_name[rndm (nbr)]); + 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)]); + } + break; } book->name = name; @@ -979,29 +975,29 @@ switch (msgtype) { - case 1: /* monster */ - nbr = sizeof (mon_author) / sizeof (char *); - strcpy (name, mon_author[RANDOM () % nbr]); - break; - case 2: /* artifacts */ - nbr = sizeof (art_author) / sizeof (char *); - strcpy (name, art_author[RANDOM () % nbr]); - break; - case 3: /* spellpath */ - nbr = sizeof (path_author) / sizeof (char *); - strcpy (name, path_author[RANDOM () % nbr]); - break; - case 4: /* alchemy */ - nbr = sizeof (formula_author) / sizeof (char *); - strcpy (name, formula_author[RANDOM () % nbr]); - break; - case 5: /* gods */ - nbr = sizeof (gods_author) / sizeof (char *); - strcpy (name, gods_author[RANDOM () % nbr]); - break; - case 6: /* msg file */ - default: - strcpy (name, book_author[RANDOM () % nbr]); + case 1: /* monster */ + nbr = sizeof (mon_author) / sizeof (char *); + assign (name, mon_author[rndm (nbr)]); + break; + case 2: /* artifacts */ + nbr = sizeof (art_author) / sizeof (char *); + assign (name, art_author[rndm (nbr)]); + break; + case 3: /* spellpath */ + nbr = sizeof (path_author) / sizeof (char *); + assign (name, path_author[rndm (nbr)]); + break; + case 4: /* alchemy */ + nbr = sizeof (formula_author) / sizeof (char *); + assign (name, formula_author[rndm (nbr)]); + break; + case 5: /* gods */ + nbr = sizeof (gods_author) / sizeof (char *); + assign (name, gods_author[rndm (nbr)]); + break; + case 6: /* msg file */ + default: + assign (name, book_author[rndm (nbr)]); } sprintf (title, "of %s", name); @@ -1105,8 +1101,8 @@ if ((tmpbook = get_archetype (t->archname)) != NULL) { tmpbook->msg = book->msg; - copy_object (tmpbook, book); - free_object (tmpbook); + tmpbook->copy_to (book); + tmpbook->destroy (); } book->title = t->authour; @@ -1175,7 +1171,7 @@ /* Lets give the book a description to individualize it some */ char new_name[MAX_BUF]; - snprintf (new_name, MAX_BUF, "%s %s", book_descrpt[RANDOM () % nbr], old_name); + snprintf (new_name, MAX_BUF, "%s %s", book_descrpt[rndm (nbr)], old_name); book->name = new_name; } @@ -1374,15 +1370,15 @@ /* artifact_msg() - generate a message detailing the properties * of 1-6 artifacts drawn sequentially from the artifact list. */ - -char * +const char * artifact_msg (int level, int booksize) { artifactlist *al = NULL; artifact *art; int chance, i, type, index; int book_entries = level > 5 ? RANDOM () % 3 + RANDOM () % 3 + 2 : RANDOM () % level + 1; - char *ch, name[MAX_BUF], buf[BOOK_BUF], sbuf[MAX_BUF]; + const char *ch; + char name[MAX_BUF], buf[BOOK_BUF], sbuf[MAX_BUF]; static char retbuf[BOOK_BUF]; object *tmp = NULL; @@ -1406,7 +1402,7 @@ while ((al == NULL) && (i < 10)); if (i == 10) /* Unable to find a message */ - return ("None"); + return "None"; /* There is no reason to start on the artifact list at the begining. Lets * take our starting position randomly... */ @@ -1419,7 +1415,7 @@ } /* the base 'generic' name for our artifact */ - strcpy (name, art_name_array[index].name); + 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"); @@ -1473,13 +1469,13 @@ strcat (buf, art->item->msg); /* properties of the artifact */ - tmp = get_object (); + 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); - free_object (tmp); + tmp->destroy (); /* add the buf if it will fit */ if (!book_overflow (retbuf, buf, booksize)) strcat (retbuf, buf); @@ -1533,7 +1529,7 @@ if (at->clone.type == SPELL && at->clone.path_attuned & pnum && ((at->clone.stats.grace && prayers) || (at->clone.stats.sp && !prayers)) && (at->clone.level < (level * 8))) { - strcpy (tmpbuf, at->clone.name); + assign (tmpbuf, at->clone.name); if (book_overflow (retbuf, tmpbuf, booksize)) break; @@ -1619,7 +1615,7 @@ /* preamble */ sprintf (retbuf, "Herein is described a project using %s: \n", formula->skill ? &formula->skill : "an unknown skill"); - if ((at = find_archetype (op_name)) != (archetype *) NULL) + if ((at = archetype::find (op_name)) != (archetype *) NULL) op_name = at->clone.name; else LOG (llevError, "formula_msg() can't find arch %s for formula.\n", op_name); @@ -1658,7 +1654,7 @@ linked_char *next; archetype *at; - at = find_archetype (formula->cauldron); + at = archetype::find (formula->cauldron); sprintf (retbuf + strlen (retbuf), " may be made at %s using the following ingredients:\n", at ? query_name (&at->clone) : "an unknown place"); @@ -1701,7 +1697,7 @@ } if (msg && !book_overflow (retbuf, msg->name, booksize)) - strcpy (retbuf, msg->name); + assign (retbuf, msg->name); else sprintf (retbuf, "\n "); @@ -1713,11 +1709,9 @@ return retbuf; } - /* god_info_msg() - generate a message detailing the properties * of a random god. Used by the book hack. b.t. */ - const char * god_info_msg (int level, int booksize) { @@ -1763,6 +1757,7 @@ if (enemy) sprintf (buf, "The gods %s and %s are enemies.\n ---\n", name, enemy); } + if (level == 3 && RANDOM () % 2) { /* enemy race, what the god's holy word effects */ const char *enemy = god->slaying; @@ -1781,13 +1776,12 @@ sprintf (buf, "%s%s\n ---\n", buf, tmpbuf); } } + if (level == 4 && RANDOM () % 2) { /* Priest of god gets these protect,vulnerable... */ - char tmpbuf[MAX_BUF], *cp; - - cp = describe_resistance (god, 1); + char tmpbuf[MAX_BUF]; - if (*cp) + 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"); @@ -1798,6 +1792,7 @@ else sprintf (buf, " "); } + if (level == 5 && RANDOM () % 2) { /* aligned race, summoning */ const char *race = god->race; /* aligned race */ @@ -1815,13 +1810,12 @@ sprintf (buf, "%s%s\n ---\n", buf, tmpbuf); } } + if (level == 6 && RANDOM () % 2) { /* blessing,curse properties of the god */ - char tmpbuf[MAX_BUF], *cp; - - cp = describe_resistance (god, 1); + char tmpbuf[MAX_BUF]; - if (*cp) + 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"); @@ -1833,6 +1827,7 @@ sprintf (buf, " "); } + if (level == 8 && RANDOM () % 2) { /* immunity, holy possession */ int has_effect = 0, tmpvar; @@ -1851,6 +1846,7 @@ sprintf (tmpbuf + strlen (tmpbuf), "Immunity to %s", attacktype_desc[tmpvar]); } } + if (has_effect) { strcat (buf, tmpbuf); @@ -1859,6 +1855,7 @@ else sprintf (buf, " "); } + if (level == 12 && RANDOM () % 2) { /* spell paths */ int has_effect = 0, tmpvar; @@ -1867,21 +1864,25 @@ 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"); + if ((tmpvar = god->path_attuned)) { has_effect = 1; DESCRIBE_PATH (tmpbuf, tmpvar, "Attuned"); } + if ((tmpvar = god->path_repelled)) { has_effect = 1; DESCRIBE_PATH (tmpbuf, tmpvar, "Repelled"); } + if ((tmpvar = god->path_denied)) { has_effect = 1; DESCRIBE_PATH (tmpbuf, tmpvar, "Denied"); } + if (has_effect) { strcat (buf, tmpbuf); @@ -1899,8 +1900,10 @@ 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"); @@ -1986,6 +1989,7 @@ } strcat (msgbuf, "\n"); /* safety -- we get ugly map saves/crashes w/o this */ + if (strlen (msgbuf) > 1) { book->msg = msgbuf; @@ -2024,15 +2028,17 @@ 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; - free (monlink); + delete monlink; } }