ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/readable.C
(Generate patch)

Comparing deliantra/server/common/readable.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:00 2006 UTC vs.
Revision 1.3 by root, Sun Sep 3 00:18:40 2006 UTC

1/* 1/*
2 * static char *rcsid_readable_c = 2 * static char *rcsid_readable_c =
3 * "$Id: readable.C,v 1.1 2006/08/13 17:16:00 elmex Exp $"; 3 * "$Id: readable.C,v 1.3 2006/09/03 00:18:40 root Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
77/* Moved these structures from struct.h to this file in 0.94.3 - they 77/* Moved these structures from struct.h to this file in 0.94.3 - they
78 * are not needed anyplace else, so why have them globally declared? 78 * are not needed anyplace else, so why have them globally declared?
79 */ 79 */
80 80
81/* 'title' and 'titlelist' are used by the readable code */ 81/* 'title' and 'titlelist' are used by the readable code */
82typedef struct titlestruct { 82typedef struct titlestruct : zero_initialised
83{
83 const char *name; /* the name of the book */ 84 shstr name; /* the name of the book */
84 const char *authour; /* the name of the book authour */ 85 shstr authour; /* the name of the book authour */
85 const char *archname; /* the archetype name of the book */ 86 shstr archname; /* the archetype name of the book */
86 int level; /* level of difficulty of this message */ 87 int level; /* level of difficulty of this message */
87 int size; /* size of the book message */ 88 int size; /* size of the book message */
88 int msg_index; /* an index value derived from book message */ 89 int msg_index; /* an index value derived from book message */
89 struct titlestruct *next; 90 struct titlestruct *next;
90} title; 91} title;
91 92
92typedef struct titleliststruct { 93typedef struct titleliststruct : zero_initialised
94{
93 int number; /* number of items in the list */ 95 int number; /* number of items in the list */
94 struct titlestruct *first_book; /* pointer to first book in this list */ 96 struct titlestruct *first_book; /* pointer to first book in this list */
95 struct titleliststruct *next; /* pointer to next book list */ 97 struct titleliststruct *next; /* pointer to next book list */
96} titlelist; 98} titlelist;
97
98 99
99/* special structure, used only by art_name_array[] */ 100/* special structure, used only by art_name_array[] */
100 101
101typedef struct namebytype 102typedef struct namebytype
102 { 103 {
456 * at the bottom of the list. Never delete a subtype because index is used as 457 * at the bottom of the list. Never delete a subtype because index is used as
457 * subtype paramater in arch files! 458 * subtype paramater in arch files!
458 */ 459 */
459static readable_message_type readable_message_types[] = 460static readable_message_type readable_message_types[] =
460{ 461{
461 /*subtype 0 */ {0,0}, 462 /*subtype 0 */ {0,0},
462 /* book messages subtypes */ 463 /* book messages subtypes */
463 /*subtype 1 */ {MSG_TYPE_BOOK, MSG_TYPE_BOOK_CLASP_1}, 464 /*subtype 1 */ {MSG_TYPE_BOOK, MSG_TYPE_BOOK_CLASP_1},
464 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_CLASP_2}, 465 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_CLASP_2},
465 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_ELEGANT_1}, 466 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_ELEGANT_1},
466 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_ELEGANT_2}, 467 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_ELEGANT_2},
467 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_QUARTO_1}, 468 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_QUARTO_1},
468 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_QUARTO_2}, 469 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_QUARTO_2},
469 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_EVOKER}, 470 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_EVOKER},
470 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_PRAYER}, 471 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_PRAYER},
471 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_PYRO}, 472 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_PYRO},
472 /*subtype 10 */ {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_SORCERER}, 473 /*subtype 10 */ {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_SORCERER},
473 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_SUMMONER}, 474 {MSG_TYPE_BOOK, MSG_TYPE_BOOK_SPELL_SUMMONER},
474 /* card messages subtypes*/ 475 /* card messages subtypes*/
475 {MSG_TYPE_CARD, MSG_TYPE_CARD_SIMPLE_1}, 476 {MSG_TYPE_CARD, MSG_TYPE_CARD_SIMPLE_1},
476 {MSG_TYPE_CARD, MSG_TYPE_CARD_SIMPLE_2}, 477 {MSG_TYPE_CARD, MSG_TYPE_CARD_SIMPLE_2},
477 {MSG_TYPE_CARD, MSG_TYPE_CARD_SIMPLE_3}, 478 {MSG_TYPE_CARD, MSG_TYPE_CARD_SIMPLE_3},
478 {MSG_TYPE_CARD, MSG_TYPE_CARD_ELEGANT_1}, 479 {MSG_TYPE_CARD, MSG_TYPE_CARD_ELEGANT_1},
479 {MSG_TYPE_CARD, MSG_TYPE_CARD_ELEGANT_2}, 480 {MSG_TYPE_CARD, MSG_TYPE_CARD_ELEGANT_2},
480 {MSG_TYPE_CARD, MSG_TYPE_CARD_ELEGANT_3}, 481 {MSG_TYPE_CARD, MSG_TYPE_CARD_ELEGANT_3},
481 {MSG_TYPE_CARD, MSG_TYPE_CARD_STRANGE_1}, 482 {MSG_TYPE_CARD, MSG_TYPE_CARD_STRANGE_1},
482 {MSG_TYPE_CARD, MSG_TYPE_CARD_STRANGE_2}, 483 {MSG_TYPE_CARD, MSG_TYPE_CARD_STRANGE_2},
483 /*subtype 20 */ {MSG_TYPE_CARD, MSG_TYPE_CARD_STRANGE_3}, 484 /*subtype 20 */ {MSG_TYPE_CARD, MSG_TYPE_CARD_STRANGE_3},
484 {MSG_TYPE_CARD, MSG_TYPE_CARD_MONEY_1}, 485 {MSG_TYPE_CARD, MSG_TYPE_CARD_MONEY_1},
485 {MSG_TYPE_CARD, MSG_TYPE_CARD_MONEY_2}, 486 {MSG_TYPE_CARD, MSG_TYPE_CARD_MONEY_2},
486 {MSG_TYPE_CARD, MSG_TYPE_CARD_MONEY_3}, 487 {MSG_TYPE_CARD, MSG_TYPE_CARD_MONEY_3},
487 488
488 /* Paper messages subtypes */ 489 /* Paper messages subtypes */
490 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_NOTE_2}, 491 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_NOTE_2},
491 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_NOTE_3}, 492 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_NOTE_3},
492 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_OLD_1}, 493 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_OLD_1},
493 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_OLD_2}, 494 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_OLD_2},
494 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_NEW_1}, 495 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_NEW_1},
495 /*subtype 30 */ {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_NEW_2}, 496 /*subtype 30 */ {MSG_TYPE_PAPER, MSG_TYPE_PAPER_LETTER_NEW_2},
496 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_ENVELOPE_1}, 497 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_ENVELOPE_1},
497 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_ENVELOPE_2}, 498 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_ENVELOPE_2},
498 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_OLD_1}, 499 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_OLD_1},
499 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_OLD_2}, 500 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_OLD_2},
500 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_NEW_1}, 501 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_NEW_1},
502 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_MAGIC}, 503 {MSG_TYPE_PAPER, MSG_TYPE_PAPER_SCROLL_MAGIC},
503 504
504 /* road signs messages subtypes */ 505 /* road signs messages subtypes */
505 {MSG_TYPE_SIGN, MSG_TYPE_SIGN_BASIC}, 506 {MSG_TYPE_SIGN, MSG_TYPE_SIGN_BASIC},
506 {MSG_TYPE_SIGN, MSG_TYPE_SIGN_DIR_LEFT}, 507 {MSG_TYPE_SIGN, MSG_TYPE_SIGN_DIR_LEFT},
507 /*subtype 40 */ {MSG_TYPE_SIGN, MSG_TYPE_SIGN_DIR_RIGHT}, 508 /*subtype 40 */ {MSG_TYPE_SIGN, MSG_TYPE_SIGN_DIR_RIGHT},
508 {MSG_TYPE_SIGN, MSG_TYPE_SIGN_DIR_BOTH}, 509 {MSG_TYPE_SIGN, MSG_TYPE_SIGN_DIR_BOTH},
509 510
510 /* stones and monument messages */ 511 /* stones and monument messages */
511 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STONE_1}, 512 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STONE_1},
512 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STONE_2}, 513 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STONE_2},
514 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STATUE_1}, 515 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STATUE_1},
515 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STATUE_2}, 516 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STATUE_2},
516 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STATUE_3}, 517 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_STATUE_3},
517 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_GRAVESTONE_1}, 518 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_GRAVESTONE_1},
518 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_GRAVESTONE_2}, 519 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_GRAVESTONE_2},
519 /*subtype 50 */ {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_GRAVESTONE_3}, 520 /*subtype 50 */ {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_GRAVESTONE_3},
520 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_1}, 521 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_1},
521 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_2}, 522 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_2},
522 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_3} 523 {MSG_TYPE_MONUMENT, MSG_TYPE_MONUMENT_WALL_3}
523}; 524};
524int last_readable_subtype = sizeof(readable_message_types)/sizeof(readable_message_type); 525int last_readable_subtype = sizeof(readable_message_types)/sizeof(readable_message_type);
540 *****************************************************************************/ 541 *****************************************************************************/
541 542
542static titlelist * 543static titlelist *
543get_empty_booklist (void) 544get_empty_booklist (void)
544{ 545{
545 titlelist *bl = (titlelist *) malloc (sizeof (titlelist)); 546 titlelist *bl = new titlelist;
546 if (bl == NULL) 547
547 fatal (OUT_OF_MEMORY);
548 bl->number = 0; 548 bl->number = 0;
549 bl->first_book = NULL; 549 bl->first_book = NULL;
550 bl->next = NULL; 550 bl->next = NULL;
551 return bl; 551 return bl;
552} 552}
553 553
554static title * 554static title *
555get_empty_book (void) 555get_empty_book (void)
556{ 556{
557 title *t = (title *) malloc (sizeof (title)); 557 title *t = new title;
558 if (t == NULL) 558
559 fatal (OUT_OF_MEMORY);
560 t->name = NULL; 559 t->name = NULL;
561 t->archname = NULL; 560 t->archname = NULL;
562 t->authour = NULL; 561 t->authour = NULL;
563 t->level = 0; 562 t->level = 0;
564 t->size = 0; 563 t->size = 0;
574{ 573{
575 titlelist *tl = booklist; 574 titlelist *tl = booklist;
576 int number = i; 575 int number = i;
577 576
578 if (number < 0) 577 if (number < 0)
579 return tl; 578 return tl;
580 579
581 while (tl && number) 580 while (tl && number)
582 { 581 {
583 if (!tl->next) 582 if (!tl->next)
584 tl->next = get_empty_booklist (); 583 tl->next = get_empty_booklist ();
585 tl = tl->next; 584 tl = tl->next;
586 number--; 585 number--;
587 } 586 }
588 587
589 return tl; 588 return tl;
590} 589}
591 590
601{ 600{
602 char *tbuf, sbuf[12], buf[MAX_BUF]; 601 char *tbuf, sbuf[12], buf[MAX_BUF];
603 int number = 0; 602 int number = 0;
604 603
605 if (!buf1 || !buf2) 604 if (!buf1 || !buf2)
606 return 0; 605 return 0;
607 sprintf (buf, "%s", buf1); 606 sprintf (buf, "%s", buf1);
608 sprintf (sbuf, "%s", buf2); 607 sprintf (sbuf, "%s", buf2);
609 tbuf = strtok (buf, sbuf); 608 tbuf = strtok (buf, sbuf);
610 while (tbuf) 609 while (tbuf)
611 { 610 {
612 number++; 611 number++;
613 tbuf = strtok (NULL, sbuf); 612 tbuf = strtok (NULL, sbuf);
614 } 613 }
615 return number; 614 return number;
616} 615}
617 616
618/* strtoktolin() - takes a string in buf1 and separates it into 617/* strtoktolin() - takes a string in buf1 and separates it into
632 strcpy(sbuf, buf2); 631 strcpy(sbuf, buf2);
633 strcpy(rbuf, " "); 632 strcpy(rbuf, " ");
634 tbuf = strtok (buf, sbuf); 633 tbuf = strtok (buf, sbuf);
635 while (tbuf && i > 0) 634 while (tbuf && i > 0)
636 { 635 {
637 strcat (rbuf, tbuf); 636 strcat (rbuf, tbuf);
638 i--; 637 i--;
639 if (i == 1 && maxi > 1) 638 if (i == 1 && maxi > 1)
640 strcat (rbuf, " and "); 639 strcat (rbuf, " and ");
641 else if (i > 0 && maxi > 1) 640 else if (i > 0 && maxi > 1)
642 strcat (rbuf, ", "); 641 strcat (rbuf, ", ");
643 else 642 else
644 strcat (rbuf, "."); 643 strcat (rbuf, ".");
645 tbuf = strtok (NULL, sbuf); 644 tbuf = strtok (NULL, sbuf);
646 } 645 }
647 return (char *) rbuf; 646 return (char *) rbuf;
648} 647}
649 648
650int 649int
651book_overflow (const char *buf1, const char *buf2, int booksize) 650book_overflow (const char *buf1, const char *buf2, int booksize)
652{ 651{
653 652
654 if (buf_overflow (buf1, buf2, BOOK_BUF - 2) /* 2 less so always room for trailing \n */ 653 if (buf_overflow (buf1, buf2, BOOK_BUF - 2) /* 2 less so always room for trailing \n */
655 || buf_overflow (buf1, buf2, booksize)) 654 || buf_overflow (buf1, buf2, booksize))
656 return 1; 655 return 1;
657 return 0; 656 return 0;
658 657
659 658
660} 659}
661 660
676 char buf[MAX_BUF], msgbuf[HUGE_BUF], fname[MAX_BUF], *cp; 675 char buf[MAX_BUF], msgbuf[HUGE_BUF], fname[MAX_BUF], *cp;
677 int comp; 676 int comp;
678 static int did_init_msgfile; 677 static int did_init_msgfile;
679 678
680 if (did_init_msgfile) 679 if (did_init_msgfile)
681 return; 680 return;
682 did_init_msgfile = 1; 681 did_init_msgfile = 1;
683 682
684 sprintf (fname, "%s/messages", settings.datadir); 683 sprintf (fname, "%s/messages", settings.datadir);
685 LOG (llevDebug, "Reading messages from %s...", fname); 684 LOG (llevDebug, "Reading messages from %s...", fname);
686 685
687 if ((fp = open_and_uncompress (fname, 0, &comp)) != NULL) 686 if ((fp = open_and_uncompress (fname, 0, &comp)) != NULL)
688 { 687 {
689 linked_char *tmp = NULL; 688 linked_char *tmp = NULL;
690 while (fgets (buf, MAX_BUF, fp) != NULL) 689 while (fgets (buf, MAX_BUF, fp) != NULL)
691 { 690 {
692 if (*buf == '#') 691 if (*buf == '#')
693 continue; 692 continue;
694 if ((cp = strchr (buf, '\n')) != NULL) 693 if ((cp = strchr (buf, '\n')) != NULL)
695 *cp = '\0'; 694 *cp = '\0';
696 cp = buf; 695 cp = buf;
697 while (*cp == ' ') /* Skip blanks */ 696 while (*cp == ' ') /* Skip blanks */
698 cp++; 697 cp++;
699 if (!strncmp (cp, "ENDMSG", 6)) 698 if (!strncmp (cp, "ENDMSG", 6))
700 { 699 {
701 if (strlen (msgbuf) > BOOK_BUF) 700 if (strlen (msgbuf) > BOOK_BUF)
702 { 701 {
703 LOG (llevDebug, "Warning: this string exceeded max book buf size:"); 702 LOG (llevDebug, "Warning: this string exceeded max book buf size:");
704 LOG (llevDebug, " %s", msgbuf); 703 LOG (llevDebug, " %s", msgbuf);
705 } 704 }
706 tmp->name = add_string (msgbuf); 705 tmp->name = msgbuf;
707 tmp->next = first_msg; 706 tmp->next = first_msg;
708 first_msg = tmp; 707 first_msg = tmp;
709 nrofmsg++; 708 nrofmsg++;
710 continue; 709 continue;
711 } 710 }
712 else if (!strncmp (cp, "MSG", 3)) 711 else if (!strncmp (cp, "MSG", 3))
713 { 712 {
714 tmp = (linked_char *) malloc (sizeof (linked_char)); 713 tmp = new linked_char;
715 strcpy (msgbuf, " "); /* reset msgbuf for new message */ 714 strcpy (msgbuf, " "); /* reset msgbuf for new message */
716 continue; 715 continue;
717 } 716 }
718 else if (!buf_overflow (msgbuf, cp, HUGE_BUF - 1)) 717 else if (!buf_overflow (msgbuf, cp, HUGE_BUF - 1))
719 { 718 {
720 strcat (msgbuf, cp); 719 strcat (msgbuf, cp);
721 strcat (msgbuf, "\n"); 720 strcat (msgbuf, "\n");
722 } 721 }
723 } 722 }
724 close_and_delete (fp, comp); 723 close_and_delete (fp, comp);
725 } 724 }
726 725
727#ifdef BOOK_MSG_DEBUG 726#ifdef BOOK_MSG_DEBUG
728 LOG (llevDebug, "\ninit_info_listfile() got %d messages.\n", nrofmsg); 727 LOG (llevDebug, "\ninit_info_listfile() got %d messages.\n", nrofmsg);
729#endif 728#endif
745 title *book = NULL; 744 title *book = NULL;
746 titlelist *bl = get_empty_booklist (); 745 titlelist *bl = get_empty_booklist ();
747 static int did_init_barch; 746 static int did_init_barch;
748 747
749 if (did_init_barch) 748 if (did_init_barch)
750 return; 749 return;
751 did_init_barch = 1; 750 did_init_barch = 1;
752 751
753 if (!booklist) 752 if (!booklist)
754 booklist = bl; 753 booklist = bl;
755 754
756 sprintf (fname, "%s/bookarch", settings.localdir); 755 sprintf (fname, "%s/bookarch", settings.localdir);
757 LOG (llevDebug, " Reading bookarch from %s...\n", fname); 756 LOG (llevDebug, " Reading bookarch from %s...\n", fname);
758 757
759 if ((fp = open_and_uncompress (fname, 0, &comp)) != NULL) 758 if ((fp = open_and_uncompress (fname, 0, &comp)) != NULL)
760 { 759 {
761 int value, type = 0; 760 int value, type = 0;
762 size_t i; 761 size_t i;
763 762
764 while (fgets (buf, MAX_BUF, fp) != NULL) 763 while (fgets (buf, MAX_BUF, fp) != NULL)
765 { 764 {
766 if (*buf == '#') 765 if (*buf == '#')
767 continue; 766 continue;
768 if ((cp = strchr (buf, '\n')) != NULL) 767 if ((cp = strchr (buf, '\n')) != NULL)
769 *cp = '\0'; 768 *cp = '\0';
770 cp = buf; 769 cp = buf;
771 while (*cp == ' ') /* Skip blanks */ 770 while (*cp == ' ') /* Skip blanks */
772 cp++; 771 cp++;
773 if (!strncmp (cp, "title", 4)) 772 if (!strncmp (cp, "title", 4))
774 { 773 {
775 book = get_empty_book (); /* init new book entry */ 774 book = get_empty_book (); /* init new book entry */
776 book->name = add_string (strchr (cp, ' ') + 1); 775 book->name = strchr (cp, ' ') + 1;
777 type = -1; 776 type = -1;
778 nroftitle++; 777 nroftitle++;
779 continue; 778 continue;
780 } 779 }
781 if (!strncmp (cp, "authour", 4)) 780 if (!strncmp (cp, "authour", 4))
782 { 781 {
783 book->authour = add_string (strchr (cp, ' ') + 1); 782 book->authour = strchr (cp, ' ') + 1;
784 } 783 }
785 if (!strncmp (cp, "arch", 4)) 784 if (!strncmp (cp, "arch", 4))
786 { 785 {
787 book->archname = add_string (strchr (cp, ' ') + 1); 786 book->archname = strchr (cp, ' ') + 1;
788 } 787 }
789 else if (sscanf (cp, "level %d", &value)) 788 else if (sscanf (cp, "level %d", &value))
790 { 789 {
791 book->level = (uint16) value; 790 book->level = (uint16) value;
792 } 791 }
793 else if (sscanf (cp, "type %d", &value)) 792 else if (sscanf (cp, "type %d", &value))
794 { 793 {
795 type = (uint16) value; 794 type = (uint16) value;
796 } 795 }
797 else if (sscanf (cp, "size %d", &value)) 796 else if (sscanf (cp, "size %d", &value))
798 { 797 {
799 book->size = (uint16) value; 798 book->size = (uint16) value;
800 } 799 }
801 else if (sscanf (cp, "index %d", &value)) 800 else if (sscanf (cp, "index %d", &value))
802 { 801 {
803 book->msg_index = (uint16) value; 802 book->msg_index = (uint16) value;
804 } 803 }
805 else if (!strncmp (cp, "end", 3)) 804 else if (!strncmp (cp, "end", 3))
806 { /* link it */ 805 { /* link it */
807 bl = get_titlelist (type); 806 bl = get_titlelist (type);
808 book->next = bl->first_book; 807 book->next = bl->first_book;
809 bl->first_book = book; 808 bl->first_book = book;
810 bl->number++; 809 bl->number++;
811 } 810 }
812 } 811 }
813 LOG (llevDebug, " book archives(used/avail): "); 812 LOG (llevDebug, " book archives(used/avail): ");
814 for (bl = booklist, i = 0; bl != NULL && i < sizeof(max_titles)/sizeof(*max_titles); bl = bl->next, i++) 813 for (bl = booklist, i = 0; bl != NULL && i < sizeof(max_titles)/sizeof(*max_titles); bl = bl->next, i++)
815 { 814 {
816 LOG (llevDebug, "(%d/%d)", bl->number, max_titles[i]); 815 LOG (llevDebug, "(%d/%d)", bl->number, max_titles[i]);
817 } 816 }
818 LOG (llevDebug, "\n"); 817 LOG (llevDebug, "\n");
819 close_and_delete (fp, comp); 818 close_and_delete (fp, comp);
820 } 819 }
821 820
822#ifdef BOOK_MSG_DEBUG 821#ifdef BOOK_MSG_DEBUG
823 LOG (llevDebug, "\n init_book_archive() got %d titles.\n", nroftitle); 822 LOG (llevDebug, "\n init_book_archive() got %d titles.\n", nroftitle);
824#endif 823#endif
834{ 833{
835 archetype *at; 834 archetype *at;
836 static int did_init_mon_info = 0; 835 static int did_init_mon_info = 0;
837 836
838 if (did_init_mon_info) 837 if (did_init_mon_info)
839 return; 838 return;
840 did_init_mon_info = 1; 839 did_init_mon_info = 1;
841 840
842 841
843 for (at = first_archetype; at != NULL; at = at->next) 842 for (at = first_archetype; at != NULL; at = at->next)
844 { 843 {
845 if (QUERY_FLAG (&at->clone, FLAG_MONSTER) && 844 if (QUERY_FLAG (&at->clone, FLAG_MONSTER) &&
846 (!QUERY_FLAG (&at->clone, FLAG_CHANGING) 845 (!QUERY_FLAG (&at->clone, FLAG_CHANGING)
847 || QUERY_FLAG (&at->clone, FLAG_UNAGGRESSIVE)) 846 || QUERY_FLAG (&at->clone, FLAG_UNAGGRESSIVE))
848 ) 847 )
849 { 848 {
850 objectlink *mon = (objectlink *) malloc (sizeof (objectlink)); 849 objectlink *mon = (objectlink *) malloc (sizeof (objectlink));
851 mon->ob = &at->clone; 850 mon->ob = &at->clone;
852 mon->id = nrofmon; 851 mon->id = nrofmon;
853 mon->next = first_mon_info; 852 mon->next = first_mon_info;
854 first_mon_info = mon; 853 first_mon_info = mon;
855 nrofmon++; 854 nrofmon++;
856 } 855 }
857 } 856 }
858 LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon); 857 LOG (llevDebug, "init_mon_info() got %d monsters\n", nrofmon);
859} 858}
860 859
861 860
901 titlelist *tl = get_titlelist (msgtype); 900 titlelist *tl = get_titlelist (msgtype);
902 int length = strlen (book->msg); 901 int length = strlen (book->msg);
903 int index = strtoint (book->msg); 902 int index = strtoint (book->msg);
904 903
905 if (msgtype < 0) 904 if (msgtype < 0)
906 return (title *) NULL; 905 return (title *) NULL;
907 906
908 if (tl) 907 if (tl)
909 t = tl->first_book; 908 t = tl->first_book;
910 while (t) 909 while (t)
911 if (t->size == length && t->msg_index == index) 910 if (t->size == length && t->msg_index == index)
912 break; 911 break;
913 else 912 else
914 t = t->next; 913 t = t->next;
915 914
916#ifdef ARCHIVE_DEBUG 915#ifdef ARCHIVE_DEBUG
917 if (t) 916 if (t)
918 LOG (llevDebug, "Found title match (list %d): %s %s (%d)\n", 917 LOG (llevDebug, "Found title match (list %d): %s %s (%d)\n",
919 msgtype, t->name, t->authour, t->msg_index); 918 msgtype, t->name, t->authour, t->msg_index);
920#endif 919#endif
921 920
922 return t; 921 return t;
923} 922}
924 923
934{ 933{
935 int nbr; 934 int nbr;
936 char name[MAX_BUF]; 935 char name[MAX_BUF];
937 936
938 if (book->type != BOOK) 937 if (book->type != BOOK)
939 return; 938 return;
940 939
941 switch (msgtype) 940 switch (msgtype)
942 { 941 {
943 case 1: /*monster */ 942 case 1: /*monster */
944 nbr = sizeof (mon_book_name) / sizeof (char *); 943 nbr = sizeof (mon_book_name) / sizeof (char *);
945 strcpy (name, mon_book_name[RANDOM () % nbr]); 944 strcpy (name, mon_book_name[RANDOM () % nbr]);
946 break; 945 break;
947 case 2: /*artifact */ 946 case 2: /*artifact */
948 nbr = sizeof (art_book_name) / sizeof (char *); 947 nbr = sizeof (art_book_name) / sizeof (char *);
949 strcpy (name, art_book_name[RANDOM () % nbr]); 948 strcpy (name, art_book_name[RANDOM () % nbr]);
950 break; 949 break;
951 case 3: /*spellpath */ 950 case 3: /*spellpath */
952 nbr = sizeof (path_book_name) / sizeof (char *); 951 nbr = sizeof (path_book_name) / sizeof (char *);
953 strcpy (name, path_book_name[RANDOM () % nbr]); 952 strcpy (name, path_book_name[RANDOM () % nbr]);
954 break; 953 break;
955 case 4: /*alchemy */ 954 case 4: /*alchemy */
956 nbr = sizeof (formula_book_name) / sizeof (char *); 955 nbr = sizeof (formula_book_name) / sizeof (char *);
957 strcpy (name, formula_book_name[RANDOM () % nbr]); 956 strcpy (name, formula_book_name[RANDOM () % nbr]);
958 break; 957 break;
959 case 5: /*gods */ 958 case 5: /*gods */
960 nbr = sizeof (gods_book_name) / sizeof (char *); 959 nbr = sizeof (gods_book_name) / sizeof (char *);
961 strcpy (name, gods_book_name[RANDOM () % nbr]); 960 strcpy (name, gods_book_name[RANDOM () % nbr]);
962 break; 961 break;
963 case 6: /*msg file */ 962 case 6: /*msg file */
964 default: 963 default:
965 if (book->weight > 2000) 964 if (book->weight > 2000)
966 { /* based on weight */ 965 { /* based on weight */
967 nbr = sizeof (heavy_book_name) / sizeof (char *); 966 nbr = sizeof (heavy_book_name) / sizeof (char *);
968 strcpy (name, heavy_book_name[RANDOM () % nbr]); 967 strcpy (name, heavy_book_name[RANDOM () % nbr]);
969 } 968 }
970 else if (book->weight < 2001) 969 else if (book->weight < 2001)
971 { 970 {
972 nbr = sizeof (light_book_name) / sizeof (char *); 971 nbr = sizeof (light_book_name) / sizeof (char *);
973 strcpy (name, light_book_name[RANDOM () % nbr]); 972 strcpy (name, light_book_name[RANDOM () % nbr]);
973 }
974 break;
974 } 975 }
975 break; 976
976 }
977 free_string (book->name);
978 book->name = add_string (name); 977 book->name = name;
979} 978}
980 979
981/* add_book_author() 980/* add_book_author()
982 * A lot like new_text_name above, but instead chooses an author 981 * A lot like new_text_name above, but instead chooses an author
983 * and sets op->title to that value 982 * and sets op->title to that value
988{ 987{
989 char title[MAX_BUF], name[MAX_BUF]; 988 char title[MAX_BUF], name[MAX_BUF];
990 int nbr = sizeof (book_author) / sizeof (char *); 989 int nbr = sizeof (book_author) / sizeof (char *);
991 990
992 if (msgtype < 0 || strlen (op->msg) < 5) 991 if (msgtype < 0 || strlen (op->msg) < 5)
993 return; 992 return;
994 993
995 switch (msgtype) 994 switch (msgtype)
996 { 995 {
997 case 1: /* monster */ 996 case 1: /* monster */
998 nbr = sizeof (mon_author) / sizeof (char *); 997 nbr = sizeof (mon_author) / sizeof (char *);
999 strcpy (name, mon_author[RANDOM () % nbr]); 998 strcpy (name, mon_author[RANDOM () % nbr]);
1000 break; 999 break;
1001 case 2: /* artifacts */ 1000 case 2: /* artifacts */
1002 nbr = sizeof (art_author) / sizeof (char *); 1001 nbr = sizeof (art_author) / sizeof (char *);
1003 strcpy (name, art_author[RANDOM () % nbr]); 1002 strcpy (name, art_author[RANDOM () % nbr]);
1004 break; 1003 break;
1005 case 3: /* spellpath */ 1004 case 3: /* spellpath */
1006 nbr = sizeof (path_author) / sizeof (char *); 1005 nbr = sizeof (path_author) / sizeof (char *);
1007 strcpy (name, path_author[RANDOM () % nbr]); 1006 strcpy (name, path_author[RANDOM () % nbr]);
1008 break; 1007 break;
1009 case 4: /* alchemy */ 1008 case 4: /* alchemy */
1010 nbr = sizeof (formula_author) / sizeof (char *); 1009 nbr = sizeof (formula_author) / sizeof (char *);
1011 strcpy (name, formula_author[RANDOM () % nbr]); 1010 strcpy (name, formula_author[RANDOM () % nbr]);
1012 break; 1011 break;
1013 case 5: /* gods */ 1012 case 5: /* gods */
1014 nbr = sizeof (gods_author) / sizeof (char *); 1013 nbr = sizeof (gods_author) / sizeof (char *);
1015 strcpy (name, gods_author[RANDOM () % nbr]); 1014 strcpy (name, gods_author[RANDOM () % nbr]);
1016 break; 1015 break;
1017 case 6: /* msg file */ 1016 case 6: /* msg file */
1018 default: 1017 default:
1019 strcpy (name, book_author[RANDOM () % nbr]); 1018 strcpy (name, book_author[RANDOM () % nbr]);
1020 } 1019 }
1021 1020
1022 sprintf (title, "of %s", name); 1021 sprintf (title, "of %s", name);
1023 op->title = add_string (title); 1022 op->title = title;
1024} 1023}
1025 1024
1026/* unique_book() - check to see if the book title/msg is unique. We 1025/* unique_book() - check to see if the book title/msg is unique. We
1027 * go through the entire list of possibilities each time. If we find 1026 * go through the entire list of possibilities each time. If we find
1028 * a match, then unique_book returns true (because inst unique). 1027 * a match, then unique_book returns true (because inst unique).
1032unique_book (const object *book, int msgtype) 1031unique_book (const object *book, int msgtype)
1033{ 1032{
1034 title *test; 1033 title *test;
1035 1034
1036 if (!booklist) 1035 if (!booklist)
1037 return 1; /* No archival entries! Must be unique! */ 1036 return 1; /* No archival entries! Must be unique! */
1038 1037
1039 /* Go through the booklist. If the author and name match, not unique so 1038 /* Go through the booklist. If the author and name match, not unique so
1040 * return 0. 1039 * return 0.
1041 */ 1040 */
1042 for (test = get_titlelist (msgtype)->first_book; test; test=test->next) { 1041 for (test = get_titlelist (msgtype)->first_book; test; test=test->next) {
1043 if (!strcmp(test->name, book->name) && !strcmp(book->title, test->authour)) 1042 if (!strcmp(test->name, book->name) && !strcmp(book->title, test->authour))
1044 return 0; 1043 return 0;
1045 } 1044 }
1046 return 1; 1045 return 1;
1047} 1046}
1048 1047
1049/* add_book_to_list() */ 1048/* add_book_to_list() */
1054 titlelist *tl = get_titlelist (msgtype); 1053 titlelist *tl = get_titlelist (msgtype);
1055 title *t; 1054 title *t;
1056 1055
1057 if (!tl) 1056 if (!tl)
1058 { 1057 {
1059 LOG (llevError, "add_book_to_list can't get booklist!\n"); 1058 LOG (llevError, "add_book_to_list can't get booklist!\n");
1060 return; 1059 return;
1061 } 1060 }
1062 1061
1063 t = get_empty_book (); 1062 t = get_empty_book ();
1064 t->name = add_string (book->name); 1063 t->name = book->name;
1065 t->authour = add_string (book->title); 1064 t->authour = book->title;
1066 t->size = strlen (book->msg); 1065 t->size = strlen (book->msg);
1067 t->msg_index = strtoint (book->msg); 1066 t->msg_index = strtoint (book->msg);
1068 t->archname = add_string (book->arch->name); 1067 t->archname = book->arch->name;
1069 t->level = book->level; 1068 t->level = book->level;
1070 1069
1071 t->next = tl->first_book; 1070 t->next = tl->first_book;
1072 tl->first_book = t; 1071 tl->first_book = t;
1073 tl->number++; 1072 tl->number++;
1075 /* We have stuff we need to write now */ 1074 /* We have stuff we need to write now */
1076 need_to_write_bookarchive=1; 1075 need_to_write_bookarchive=1;
1077 1076
1078#ifdef ARCHIVE_DEBUG 1077#ifdef ARCHIVE_DEBUG
1079 LOG (llevDebug, "Archiving new title: %s %s (%d)\n", book->name, 1078 LOG (llevDebug, "Archiving new title: %s %s (%d)\n", book->name,
1080 book->title, msgtype); 1079 book->title, msgtype);
1081#endif 1080#endif
1082 1081
1083} 1082}
1084 1083
1085 1084
1099 int nbr = sizeof (book_descrpt) / sizeof (char *); 1098 int nbr = sizeof (book_descrpt) / sizeof (char *);
1100 1099
1101 switch (book->type) 1100 switch (book->type)
1102 { 1101 {
1103 case BOOK: 1102 case BOOK:
1104 { 1103 {
1105 titlelist *tl = get_titlelist (msgtype); 1104 titlelist *tl = get_titlelist (msgtype);
1106 title *t = NULL; 1105 title *t = NULL;
1107 int tries = 0; 1106 int tries = 0;
1108 /* look to see if our msg already been archived. If so, alter 1107 /* look to see if our msg already been archived. If so, alter
1109 * the book to match the archival text. If we fail to match, 1108 * the book to match the archival text. If we fail to match,
1110 * then we archive the new title/name/msg combo if there is 1109 * then we archive the new title/name/msg combo if there is
1111 * room on the titlelist. 1110 * room on the titlelist.
1112 */ 1111 */
1113 1112
1114 if ((strlen (book->msg) > 5) && (t = find_title (book, msgtype))) 1113 if ((strlen (book->msg) > 5) && (t = find_title (book, msgtype)))
1115 { 1114 {
1116 object *tmpbook; 1115 object *tmpbook;
1117 1116
1118 /* alter book properties */ 1117 /* alter book properties */
1119 if ((tmpbook = get_archetype (t->archname)) != NULL) 1118 if ((tmpbook = get_archetype (t->archname)) != NULL)
1120 { 1119 {
1121 if (tmpbook->msg) 1120 tmpbook->msg = book->msg;
1122 free_string (book->msg); 1121 copy_object (tmpbook, book);
1123 tmpbook->msg = add_string (book->msg); 1122 free_object (tmpbook);
1124 copy_object (tmpbook, book); 1123 }
1125 free_object (tmpbook);
1126 }
1127 1124
1128 book->title = add_string (t->authour); 1125 book->title = t->authour;
1129 free_string (book->name); 1126 book->name = t->name;
1130 book->name = add_string (t->name);
1131 book->level = t->level; 1127 book->level = t->level;
1132 } 1128 }
1133 /* Don't have any default title, so lets make up a new one */ 1129 /* Don't have any default title, so lets make up a new one */
1134 else 1130 else
1135 { 1131 {
1136 int numb, maxnames = max_titles[msgtype]; 1132 int numb, maxnames = max_titles[msgtype];
1137 const char *old_title; 1133 const char *old_title;
1138 const char *old_name; 1134 const char *old_name;
1139 1135
1140 old_title = book->title ? add_string(book->title) : NULL; 1136 old_title = book->title;
1141 old_name = add_string(book->name); 1137 old_name = book->name;
1142 1138
1143 /* some pre-generated books have title already set (from 1139 /* some pre-generated books have title already set (from
1144 * maps), also don't bother looking for unique title if 1140 * maps), also don't bother looking for unique title if
1145 * we already used up all the available names! */ 1141 * we already used up all the available names! */
1146 1142
1147 if (!tl) 1143 if (!tl)
1148 { 1144 {
1149 LOG (llevError, "change_book_name(): can't find title list\n"); 1145 LOG (llevError, "change_book_name(): can't find title list\n");
1150 numb = 0; 1146 numb = 0;
1151 } 1147 }
1152 else 1148 else
1153 numb = tl->number; 1149 numb = tl->number;
1154 1150
1155 if (numb == maxnames) 1151 if (numb == maxnames)
1156 { 1152 {
1157#ifdef ARCHIVE_DEBUG 1153#ifdef ARCHIVE_DEBUG
1158 LOG (llevDebug, "titles for list %d full (%d possible).\n", 1154 LOG (llevDebug, "titles for list %d full (%d possible).\n",
1159 msgtype, maxnames); 1155 msgtype, maxnames);
1160#endif 1156#endif
1161 if (old_title != NULL) 1157 break;
1162 free_string(old_title); 1158 }
1163 free_string(old_name);
1164 break;
1165 }
1166 /* shouldnt change map-maker books */ 1159 /* shouldnt change map-maker books */
1167 else if (!book->title) 1160 else if (!book->title)
1168 do 1161 do
1169 { 1162 {
1170 /* random book name */ 1163 /* random book name */
1171 new_text_name (book, msgtype); 1164 new_text_name (book, msgtype);
1172 add_author (book, msgtype); /* random author */ 1165 add_author (book, msgtype); /* random author */
1173 tries++; 1166 tries++;
1174 } 1167 }
1175 while (!unique_book (book, msgtype) && tries < MAX_TITLE_CHECK); 1168 while (!unique_book (book, msgtype) && tries < MAX_TITLE_CHECK);
1176 1169
1177 /* Now deal with 2 cases. 1170 /* Now deal with 2 cases.
1178 * 1)If no space for a new title exists lets just restore 1171 * 1)If no space for a new title exists lets just restore
1179 * the old book properties. Remember, if the book had 1172 * the old book properties. Remember, if the book had
1180 * matchd an older entry on the titlelist, we shouldnt 1173 * matchd an older entry on the titlelist, we shouldnt
1181 * have called this routine in the first place! 1174 * have called this routine in the first place!
1182 * 2) If we got a unique title, we need to add it to 1175 * 2) If we got a unique title, we need to add it to
1183 * the list. 1176 * the list.
1184 */ 1177 */
1185 1178
1186 if (tries == MAX_TITLE_CHECK || numb == maxnames) 1179 if (tries == MAX_TITLE_CHECK || numb == maxnames)
1187 { /* got to check maxnames again */ 1180 { /* got to check maxnames again */
1188#ifdef ARCHIVE_DEBUG 1181#ifdef ARCHIVE_DEBUG
1189 LOG (llevDebug, "Failed to obtain unique title for %s %s (names:%d/%d)\n", 1182 LOG (llevDebug, "Failed to obtain unique title for %s %s (names:%d/%d)\n",
1190 book->name, book->title, numb, maxnames); 1183 book->name, book->title, numb, maxnames);
1191#endif 1184#endif
1192 /* restore old book properties here */ 1185 /* restore old book properties here */
1193 free_string (book->name); 1186 book->title = old_title;
1194 free_string (book->title);
1195 if (old_title!=NULL)
1196 book->title = add_string (old_title);
1197 1187
1198 if (RANDOM () % 4) { 1188 if (RANDOM () % 4) {
1199 /* Lets give the book a description to individualize it some */ 1189 /* Lets give the book a description to individualize it some */
1200 char new_name[MAX_BUF]; 1190 char new_name[MAX_BUF];
1201 snprintf (new_name, MAX_BUF, "%s %s", book_descrpt[RANDOM () % nbr], old_name); 1191 snprintf (new_name, MAX_BUF, "%s %s", book_descrpt[RANDOM () % nbr], old_name);
1202 1192
1203 book->name = add_string (new_name); 1193 book->name = new_name;
1204 } else { 1194 } else {
1205 book->name = add_string (old_name); 1195 book->name = old_name;
1206 } 1196 }
1207 } 1197 }
1208 else if (book->title && strlen (book->msg) > 5) { /* archive if long msg texts */ 1198 else if (book->title && strlen (book->msg) > 5) { /* archive if long msg texts */
1209 add_book_to_list (book, msgtype); 1199 add_book_to_list (book, msgtype);
1210 } 1200 }
1211 1201 }
1212 if (old_title != NULL) 1202 break;
1213 free_string(old_title); 1203 }
1214 free_string(old_name);
1215
1216 }
1217 break;
1218 }
1219 1204
1220 default: 1205 default:
1221 LOG (llevError, "change_book_name() called w/ illegal obj type.\n"); 1206 LOG (llevError, "change_book_name() called w/ illegal obj type.\n");
1222 return; 1207 return;
1223 } 1208 }
1224} 1209}
1225 1210
1226/***************************************************************************** 1211/*****************************************************************************
1227 * 1212 *
1247 objectlink *mon = first_mon_info; 1232 objectlink *mon = first_mon_info;
1248 int i = 0, monnr; 1233 int i = 0, monnr;
1249 1234
1250 /* safety check. Problem w/ init_mon_info list? */ 1235 /* safety check. Problem w/ init_mon_info list? */
1251 if (!nrofmon || !mon) 1236 if (!nrofmon || !mon)
1252 return (object *) NULL; 1237 return (object *) NULL;
1253 1238
1254 if (!level) 1239 if (!level)
1255 { 1240 {
1256 /* lets get a random monster from the mon_info linked list */ 1241 /* lets get a random monster from the mon_info linked list */
1257 monnr = RANDOM () % nrofmon; 1242 monnr = RANDOM () % nrofmon;
1258 1243
1259 for (mon = first_mon_info, i = 0; mon; mon = mon->next) 1244 for (mon = first_mon_info, i = 0; mon; mon = mon->next)
1260 if (i++ == monnr) 1245 if (i++ == monnr)
1261 break; 1246 break;
1262 1247
1263 if (!mon) 1248 if (!mon)
1264 { 1249 {
1265 LOG (llevError, "get_random_mon: Didn't find a monster when we should have\n"); 1250 LOG (llevError, "get_random_mon: Didn't find a monster when we should have\n");
1266 return NULL; 1251 return NULL;
1267 } 1252 }
1268 return mon->ob; 1253 return mon->ob;
1269 } 1254 }
1270 1255
1271 /* Case where we are searching by level. Redone 971225 to be clearer 1256 /* Case where we are searching by level. Redone 971225 to be clearer
1272 * and more random. Before, it looks like it took a random monster from 1257 * and more random. Before, it looks like it took a random monster from
1273 * the list, and then returned the first monster after that which was 1258 * the list, and then returned the first monster after that which was
1280 * are a group of high level monsters all around each other. 1265 * are a group of high level monsters all around each other.
1281 */ 1266 */
1282 1267
1283 /* First count number of monsters meeting level criteria */ 1268 /* First count number of monsters meeting level criteria */
1284 for (mon = first_mon_info, i = 0; mon; mon = mon->next) 1269 for (mon = first_mon_info, i = 0; mon; mon = mon->next)
1285 if (mon->ob->level >= level) 1270 if (mon->ob->level >= level)
1286 i++; 1271 i++;
1287 1272
1288 if (i == 0) 1273 if (i == 0)
1289 { 1274 {
1290 LOG (llevError, "get_random_mon() couldn't return monster for level %d\n", 1275 LOG (llevError, "get_random_mon() couldn't return monster for level %d\n",
1291 level); 1276 level);
1292 return NULL; 1277 return NULL;
1293 } 1278 }
1294 1279
1295 monnr = RANDOM () % i; 1280 monnr = RANDOM () % i;
1296 for (mon = first_mon_info; mon; mon = mon->next) 1281 for (mon = first_mon_info; mon; mon = mon->next)
1297 if (mon->ob->level >= level && monnr-- == 0) 1282 if (mon->ob->level >= level && monnr-- == 0)
1298 return mon->ob; 1283 return mon->ob;
1299 1284
1300 if (!mon) 1285 if (!mon)
1301 { 1286 {
1302 LOG (llevError, "get_random_mon(): didn't find a monster when we should have\n"); 1287 LOG (llevError, "get_random_mon(): didn't find a monster when we should have\n");
1303 return NULL; 1288 return NULL;
1304 } 1289 }
1305 return NULL; /* Should be unreached, by keeps warnings down */ 1290 return NULL; /* Should be unreached, by keeps warnings down */
1306} 1291}
1307 1292
1308/* 1293/*
1313char * 1298char *
1314mon_desc (const object *mon) 1299mon_desc (const object *mon)
1315{ 1300{
1316 static char retbuf[HUGE_BUF]; 1301 static char retbuf[HUGE_BUF];
1317 1302
1318 sprintf (retbuf, " *** %s ***\n", mon->name); 1303 sprintf (retbuf, " *** %s ***\n", &mon->name);
1319 strcat (retbuf, describe_item(mon, NULL)); 1304 strcat (retbuf, describe_item(mon, NULL));
1320 1305
1321 return retbuf; 1306 return retbuf;
1322} 1307}
1323 1308
1331get_next_mon (object *tmp) 1316get_next_mon (object *tmp)
1332{ 1317{
1333 objectlink *mon; 1318 objectlink *mon;
1334 1319
1335 for (mon = first_mon_info; mon; mon = mon->next) 1320 for (mon = first_mon_info; mon; mon = mon->next)
1336 if (mon->ob == tmp) 1321 if (mon->ob == tmp)
1337 break; 1322 break;
1338 1323
1339 /* didn't find a match */ 1324 /* didn't find a match */
1340 if (!mon) 1325 if (!mon)
1341 return NULL; 1326 return NULL;
1342 if (mon->next) 1327 if (mon->next)
1343 return mon->next->ob; 1328 return mon->next->ob;
1344 else 1329 else
1345 return first_mon_info->ob; 1330 return first_mon_info->ob;
1346 1331
1347} 1332}
1348 1333
1349 1334
1350 1335
1369 * of text! (and flood out the available number of titles 1354 * of text! (and flood out the available number of titles
1370 * in the archive in a snap!) -b.t. 1355 * in the archive in a snap!) -b.t.
1371 */ 1356 */
1372 tmp = get_random_mon (level * 3); 1357 tmp = get_random_mon (level * 3);
1373 while (tmp) { 1358 while (tmp) {
1374 /* monster description */ 1359 /* monster description */
1375 sprintf (tmpbuf, "\n---\n%s", mon_desc (tmp)); 1360 sprintf (tmpbuf, "\n---\n%s", mon_desc (tmp));
1376 1361
1377 if (!book_overflow (retbuf, tmpbuf, booksize)) 1362 if (!book_overflow (retbuf, tmpbuf, booksize))
1378 strcat (retbuf, tmpbuf); 1363 strcat (retbuf, tmpbuf);
1379 else 1364 else
1380 break; 1365 break;
1381 1366
1382 /* Note that the value this returns is not based on level */ 1367 /* Note that the value this returns is not based on level */
1383 tmp = get_next_mon (tmp); 1368 tmp = get_next_mon (tmp);
1384 } 1369 }
1385 1370
1386#ifdef BOOK_MSG_DEBUG 1371#ifdef BOOK_MSG_DEBUG
1387 LOG (llevDebug, "\n mon_info_msg() created strng: %d\n", strlen (retbuf)); 1372 LOG (llevDebug, "\n mon_info_msg() created strng: %d\n", strlen (retbuf));
1388 fprintf (logfile, " MADE THIS:\n%s\n", retbuf); 1373 fprintf (logfile, " MADE THIS:\n%s\n", retbuf);
1411 static char retbuf[BOOK_BUF]; 1396 static char retbuf[BOOK_BUF];
1412 object *tmp = NULL; 1397 object *tmp = NULL;
1413 1398
1414 /* values greater than 5 create msg buffers that are too big! */ 1399 /* values greater than 5 create msg buffers that are too big! */
1415 if (book_entries > 5) 1400 if (book_entries > 5)
1416 book_entries = 5; 1401 book_entries = 5;
1417 1402
1418 /* lets determine what kind of artifact type randomly. 1403 /* lets determine what kind of artifact type randomly.
1419 * Right now legal artifacts only come from those listed 1404 * Right now legal artifacts only come from those listed
1420 * in art_name_array. Also, we check to be sure an artifactlist 1405 * in art_name_array. Also, we check to be sure an artifactlist
1421 * for that type exists! 1406 * for that type exists!
1422 */ 1407 */
1423 i=0; 1408 i=0;
1424 do { 1409 do {
1425 index = RANDOM () % (sizeof (art_name_array) / sizeof (arttypename)); 1410 index = RANDOM () % (sizeof (art_name_array) / sizeof (arttypename));
1426 type = art_name_array[index].type; 1411 type = art_name_array[index].type;
1427 al = find_artifactlist (type); 1412 al = find_artifactlist (type);
1428 i++; 1413 i++;
1429 } while ((al == NULL) && (i<10)); 1414 } while ((al == NULL) && (i<10));
1430 1415
1431 if (i==10) /* Unable to find a message */ 1416 if (i==10) /* Unable to find a message */
1432 return("None"); 1417 return("None");
1433 1418
1434 /* There is no reason to start on the artifact list at the begining. Lets 1419 /* There is no reason to start on the artifact list at the begining. Lets
1435 * take our starting position randomly... */ 1420 * take our starting position randomly... */
1436 art = al->items; 1421 art = al->items;
1437 for (i = RANDOM () % level + RANDOM () % 2 + 1; i > 0; i--) 1422 for (i = RANDOM () % level + RANDOM () % 2 + 1; i > 0; i--)
1438 { 1423 {
1439 if (art == NULL) 1424 if (art == NULL)
1440 art = al->items; /* hmm, out of stuff, loop back around */ 1425 art = al->items; /* hmm, out of stuff, loop back around */
1441 art = art->next; 1426 art = art->next;
1442 } 1427 }
1443 1428
1444 /* the base 'generic' name for our artifact */ 1429 /* the base 'generic' name for our artifact */
1445 strcpy(name, art_name_array[index].name); 1430 strcpy(name, art_name_array[index].name);
1446 1431
1447 /* Ok, lets print out the contents */ 1432 /* Ok, lets print out the contents */
1448 sprintf (retbuf, "Herein %s detailed %s...\n", book_entries > 1 ? "are" : "is", 1433 sprintf (retbuf, "Herein %s detailed %s...\n", book_entries > 1 ? "are" : "is",
1449 book_entries > 1 ? "some artifacts" : "an artifact"); 1434 book_entries > 1 ? "some artifacts" : "an artifact");
1450 1435
1451 /* artifact msg attributes loop. Lets keep adding entries to the 'book' 1436 /* artifact msg attributes loop. Lets keep adding entries to the 'book'
1452 * as long as we have space up to the allowed max # (book_entires) 1437 * as long as we have space up to the allowed max # (book_entires)
1453 */ 1438 */
1454 while (book_entries > 0) 1439 while (book_entries > 0)
1455 { 1440 {
1456 1441
1457 if (art == NULL) 1442 if (art == NULL)
1458 art = al->items; 1443 art = al->items;
1459 1444
1460 /* separator of items */ 1445 /* separator of items */
1461 strcpy (buf, "--- \n"); 1446 strcpy (buf, "--- \n");
1462 1447
1463 /* Name */ 1448 /* Name */
1464 if (art->allowed != NULL && strcmp (art->allowed->name, "All")) 1449 if (art->allowed != NULL && strcmp (art->allowed->name, "All"))
1465 { 1450 {
1466 linked_char *temp, *next = art->allowed; 1451 linked_char *temp, *next = art->allowed;
1467 do 1452 do
1468 { 1453 {
1469 temp = next; 1454 temp = next;
1470 next = next->next; 1455 next = next->next;
1471 } 1456 }
1472 while ((next != (linked_char *) NULL) && !RANDOM () % 2); 1457 while (next && !RANDOM () % 2);
1473 sprintf (buf, "%s A %s of %s", buf, temp->name, art->item->name); 1458 sprintf (buf, "%s A %s of %s", buf, &temp->name, &art->item->name);
1474 } 1459 }
1475 else /* default name is used */ 1460 else /* default name is used */
1476 sprintf (buf, "%s The %s of %s", buf, name, art->item->name); 1461 sprintf (buf, "%s The %s of %s", buf, name, &art->item->name);
1477 1462
1478 /* chance of finding */ 1463 /* chance of finding */
1479 chance = (int) (100 * ((float) art->chance / al->total_chance)); 1464 chance = (int) (100 * ((float) art->chance / al->total_chance));
1480 if (chance >= 20) 1465 if (chance >= 20)
1481 sprintf (sbuf, "an uncommon"); 1466 sprintf (sbuf, "an uncommon");
1482 else if (chance >= 10) 1467 else if (chance >= 10)
1483 sprintf (sbuf, "an unusual"); 1468 sprintf (sbuf, "an unusual");
1484 else if (chance >= 5) 1469 else if (chance >= 5)
1485 sprintf (sbuf, "a rare"); 1470 sprintf (sbuf, "a rare");
1486 else 1471 else
1487 sprintf (sbuf, "a very rare"); 1472 sprintf (sbuf, "a very rare");
1488 sprintf (buf, "%s is %s\n", buf, sbuf); 1473 sprintf (buf, "%s is %s\n", buf, sbuf);
1489 1474
1490 /* value of artifact */ 1475 /* value of artifact */
1491 sprintf (buf, "%s item with a value that is %d times normal.\n", 1476 sprintf (buf, "%s item with a value that is %d times normal.\n",
1492 buf, art->item->value); 1477 buf, art->item->value);
1493 1478
1494 /* include the message about the artifact, if exists, and book 1479 /* include the message about the artifact, if exists, and book
1495 * level is kinda high */ 1480 * level is kinda high */
1496 if (art->item->msg && (RANDOM () % 4 + 1) < level && 1481 if (art->item->msg && (RANDOM () % 4 + 1) < level &&
1497 !((strlen (art->item->msg) + strlen (buf)) > BOOK_BUF)) 1482 !((strlen (art->item->msg) + strlen (buf)) > BOOK_BUF))
1498 strcat(buf, art->item->msg); 1483 strcat(buf, art->item->msg);
1499 1484
1500 /* properties of the artifact */ 1485 /* properties of the artifact */
1501 tmp = get_object (); 1486 tmp = get_object ();
1502 add_abilities (tmp, art->item); 1487 add_abilities (tmp, art->item);
1503 tmp->type = type; 1488 tmp->type = type;
1504 SET_FLAG (tmp, FLAG_IDENTIFIED); 1489 SET_FLAG (tmp, FLAG_IDENTIFIED);
1505 if ((ch = describe_item (tmp, NULL)) != NULL && strlen (ch) > 1) 1490 if ((ch = describe_item (tmp, NULL)) != NULL && strlen (ch) > 1)
1506 sprintf (buf, "%s Properties of this artifact include: \n %s \n", 1491 sprintf (buf, "%s Properties of this artifact include: \n %s \n",
1507 buf, ch); 1492 buf, ch);
1508 free_object(tmp); 1493 free_object(tmp);
1509 /* add the buf if it will fit */ 1494 /* add the buf if it will fit */
1510 if (!book_overflow (retbuf, buf, booksize)) 1495 if (!book_overflow (retbuf, buf, booksize))
1511 strcat (retbuf, buf); 1496 strcat (retbuf, buf);
1512 else 1497 else
1513 break; 1498 break;
1514 1499
1515 art = art->next; 1500 art = art->next;
1516 book_entries--; 1501 book_entries--;
1517 } 1502 }
1518 1503
1519#ifdef BOOK_MSG_DEBUG 1504#ifdef BOOK_MSG_DEBUG
1520 LOG (llevDebug, "artifact_msg() created strng: %d\n", strlen (retbuf)); 1505 LOG (llevDebug, "artifact_msg() created strng: %d\n", strlen (retbuf));
1521 fprintf (logfile, " MADE THIS:\n%s", retbuf); 1506 fprintf (logfile, " MADE THIS:\n%s", retbuf);
1542 uint32 pnum = (path == -1) ? PATH_NULL : spellpathdef[path]; 1527 uint32 pnum = (path == -1) ? PATH_NULL : spellpathdef[path];
1543 archetype *at; 1528 archetype *at;
1544 1529
1545 /* Preamble */ 1530 /* Preamble */
1546 sprintf (retbuf, "Herein are detailed the names of %s\n", 1531 sprintf (retbuf, "Herein are detailed the names of %s\n",
1547 prayers ? "prayers": "incantations"); 1532 prayers ? "prayers": "incantations");
1548 1533
1549 if (path == -1) 1534 if (path == -1)
1550 strcat (retbuf, "having no known spell path.\n"); 1535 strcat (retbuf, "having no known spell path.\n");
1551 else 1536 else
1552 sprintf (retbuf, "%sbelonging to the path of %s:\n", retbuf, 1537 sprintf (retbuf, "%sbelonging to the path of %s:\n", retbuf,
1553 spellpathnames[path]); 1538 spellpathnames[path]);
1554 1539
1555 for (at=first_archetype; at != NULL; at=at->next) { 1540 for (at=first_archetype; at != NULL; at=at->next) {
1556 /* Determine if this is an appropriate spell. Must 1541 /* Determine if this is an appropriate spell. Must
1557 * be of matching path, must be of appropriate type (prayer 1542 * be of matching path, must be of appropriate type (prayer
1558 * or not), and must be within the valid level range. 1543 * or not), and must be within the valid level range.
1559 */ 1544 */
1560 if (at->clone.type == SPELL && at->clone.path_attuned & pnum && 1545 if (at->clone.type == SPELL && at->clone.path_attuned & pnum &&
1561 ((at->clone.stats.grace && prayers) || (at->clone.stats.sp && !prayers)) && 1546 ((at->clone.stats.grace && prayers) || (at->clone.stats.sp && !prayers)) &&
1562 (at->clone.level < (level * 8))) { 1547 (at->clone.level < (level * 8))) {
1563 strcpy (tmpbuf, at->clone.name); 1548 strcpy (tmpbuf, at->clone.name);
1564 1549
1565 if (book_overflow (retbuf, tmpbuf, booksize)) 1550 if (book_overflow (retbuf, tmpbuf, booksize))
1566 break; 1551 break;
1567 else { 1552 else {
1568 if (did_first_sp) 1553 if (did_first_sp)
1569 strcat (retbuf, ",\n"); 1554 strcat (retbuf, ",\n");
1570 did_first_sp = 1; 1555 did_first_sp = 1;
1571 strcat (retbuf, tmpbuf); 1556 strcat (retbuf, tmpbuf);
1572 } 1557 }
1573 } 1558 }
1574 } 1559 }
1575 /* Geez, no spells were generated. */ 1560 /* Geez, no spells were generated. */
1576 if (!did_first_sp) { 1561 if (!did_first_sp) {
1577 if (RANDOM () % 4) /* usually, lets make a recursive call... */ 1562 if (RANDOM () % 4) /* usually, lets make a recursive call... */
1578 spellpath_msg (level, booksize); 1563 spellpath_msg (level, booksize);
1579 else /* give up, cause knowing no spells exist for path is info too. */ 1564 else /* give up, cause knowing no spells exist for path is info too. */
1580 strcat (retbuf, "\n - no known spells exist -\n"); 1565 strcat (retbuf, "\n - no known spells exist -\n");
1581 } 1566 }
1582 else { 1567 else {
1583 strcat (retbuf, "\n"); 1568 strcat (retbuf, "\n");
1584 } 1569 }
1585 return retbuf; 1570 return retbuf;
1586} 1571}
1587 1572
1588 1573
1601 * ingredients) the formula can be. 1586 * ingredients) the formula can be.
1602 */ 1587 */
1603 fl = get_formulalist (((RANDOM () % level) / 3) + 1); 1588 fl = get_formulalist (((RANDOM () % level) / 3) + 1);
1604 1589
1605 if (!fl) 1590 if (!fl)
1606 fl = get_formulalist (1); /* safety */ 1591 fl = get_formulalist (1); /* safety */
1607 1592
1608 if (fl->total_chance == 0) 1593 if (fl->total_chance == 0)
1609 { 1594 {
1610 book->msg = add_string(" <indecipherable text>\n"); 1595 book->msg = "<indecipherable text>\n";
1611 new_text_name(book, 4); 1596 new_text_name(book, 4);
1612 add_author(book,4); 1597 add_author(book,4);
1613 return; 1598 return;
1614 } 1599 }
1615 1600
1616 /* get a random formula, weighted by its bookchance */ 1601 /* get a random formula, weighted by its bookchance */
1617 chance = RANDOM () % fl->total_chance; 1602 chance = RANDOM () % fl->total_chance;
1618 for (formula = fl->items; formula != NULL; formula = formula->next) { 1603 for (formula = fl->items; formula != NULL; formula = formula->next) {
1619 chance -= formula->chance; 1604 chance -= formula->chance;
1620 if (chance <= 0) 1605 if (chance <= 0)
1621 break; 1606 break;
1622 } 1607 }
1623 1608
1624 if (!formula || formula->arch_names <= 0) { 1609 if (!formula || formula->arch_names <= 0) {
1625 book->msg = add_string(" <indecipherable text>\n"); 1610 book->msg = "<indecipherable text>\n";
1626 new_text_name(book, 4); 1611 new_text_name(book, 4);
1627 add_author(book,4); 1612 add_author(book,4);
1628 1613
1629 } else { 1614 } else {
1630 /* looks like a formula was found. Base the amount 1615 /* looks like a formula was found. Base the amount
1631 * of information on the booklevel and the spellevel 1616 * of information on the booklevel and the spellevel
1632 * of the formula. */ 1617 * of the formula. */
1633 1618
1634 const char *op_name = formula->arch_name[RANDOM()%formula->arch_names]; 1619 const char *op_name = formula->arch_name[RANDOM()%formula->arch_names];
1635 archetype *at; 1620 archetype *at;
1636 1621
1637 /* preamble */ 1622 /* preamble */
1638 sprintf(retbuf, "Herein is described a project using %s: \n", 1623 sprintf(retbuf, "Herein is described a project using %s: \n",
1639 formula->skill?formula->skill:"an unknown skill"); 1624 formula->skill?formula->skill:"an unknown skill");
1640 1625
1641 if ((at = find_archetype (op_name)) != (archetype *) NULL) 1626 if ((at = find_archetype (op_name)) != (archetype *) NULL)
1642 op_name = at->clone.name; 1627 op_name = at->clone.name;
1643 else 1628 else
1644 LOG (llevError, "formula_msg() can't find arch %s for formula.\n", 1629 LOG (llevError, "formula_msg() can't find arch %s for formula.\n",
1645 op_name); 1630 op_name);
1646 1631
1647 /* item name */ 1632 /* item name */
1648 if (strcmp (formula->title, "NONE")) { 1633 if (strcmp (formula->title, "NONE")) {
1649 sprintf (retbuf, "%sThe %s of %s", retbuf, op_name, formula->title); 1634 sprintf (retbuf, "%sThe %s of %s", retbuf, op_name, formula->title);
1650 /* This results in things like pile of philo. sulfur. 1635 /* This results in things like pile of philo. sulfur.
1651 * while philo. sulfur may look better, without this, 1636 * while philo. sulfur may look better, without this,
1652 * you get things like 'the wise' because its missing the 1637 * you get things like 'the wise' because its missing the
1653 * water of section. 1638 * water of section.
1654 */ 1639 */
1655 sprintf(title,"%s: %s of %s", 1640 sprintf(title,"%s: %s of %s",
1656 formula_book_name[RANDOM() % (sizeof(formula_book_name) / sizeof(char*))], 1641 formula_book_name[RANDOM() % (sizeof(formula_book_name) / sizeof(char*))],
1657 op_name, formula->title); 1642 op_name, formula->title);
1658 } 1643 }
1659 else 1644 else
1660 { 1645 {
1661 sprintf (retbuf, "%sThe %s", retbuf, op_name); 1646 sprintf (retbuf, "%sThe %s", retbuf, op_name);
1662 sprintf(title,"%s: %s", 1647 sprintf(title,"%s: %s",
1663 formula_book_name[RANDOM() % (sizeof(formula_book_name) / sizeof(char*))], 1648 formula_book_name[RANDOM() % (sizeof(formula_book_name) / sizeof(char*))],
1664 op_name); 1649 op_name);
1665 if (at->clone.title) 1650 if (at->clone.title)
1666 { 1651 {
1667 strcat (retbuf, " "); 1652 strcat (retbuf, " ");
1668 strcat (retbuf, at->clone.title); 1653 strcat (retbuf, at->clone.title);
1669 strcat(title, " "); 1654 strcat(title, " ");
1670 strcat(title, at->clone.title); 1655 strcat(title, at->clone.title);
1671 } 1656 }
1672 } 1657 }
1673 /* Lets name the book something meaningful ! */ 1658 /* Lets name the book something meaningful ! */
1674 if (book->name) free_string(book->name); 1659 book->name = title;
1675 book->name = add_string(title);
1676 if (book->title) {
1677 free_string(book->title);
1678 book->title = NULL; 1660 book->title = NULL;
1679 }
1680 1661
1681 /* ingredients to make it */ 1662 /* ingredients to make it */
1682 if (formula->ingred != NULL) 1663 if (formula->ingred != NULL)
1683 { 1664 {
1684 linked_char *next; 1665 linked_char *next;
1685 archetype *at; 1666 archetype *at;
1686 1667
1687 at = find_archetype(formula->cauldron); 1668 at = find_archetype(formula->cauldron);
1688 1669
1689 sprintf(retbuf + strlen(retbuf), 1670 sprintf(retbuf + strlen(retbuf),
1690 " may be made at %s using the following ingredients:\n", 1671 " may be made at %s using the following ingredients:\n",
1691 at?query_name(&at->clone):"an unknown place"); 1672 at?query_name(&at->clone):"an unknown place");
1692 1673
1693 for (next = formula->ingred; next != NULL; next = next->next) 1674 for (next = formula->ingred; next != NULL; next = next->next)
1694 { 1675 {
1695 strcat (retbuf, next->name); 1676 strcat (retbuf, next->name);
1696 strcat (retbuf, "\n"); 1677 strcat (retbuf, "\n");
1697 } 1678 }
1698 } 1679 }
1699 else 1680 else
1700 LOG (llevError, "formula_msg() no ingredient list for object %s of %s\n", 1681 LOG (llevError, "formula_msg() no ingredient list for object %s of %s\n",
1701 op_name, formula->title); 1682 op_name, formula->title);
1702 if (retbuf[strlen(retbuf)-1]!= '\n') strcat(retbuf, "\n"); 1683 if (retbuf[strlen(retbuf)-1]!= '\n') strcat(retbuf, "\n");
1703 if (book->msg) free_string(book->msg); 1684
1704 book->msg = add_string(retbuf); 1685 book->msg = retbuf;
1705 } 1686 }
1706} 1687}
1707 1688
1708 1689
1709/* msgfile_msg() - generate a message drawn randomly from a 1690/* msgfile_msg() - generate a message drawn randomly from a
1719 linked_char *msg = NULL; 1700 linked_char *msg = NULL;
1720 1701
1721 /* get a random message for the 'book' from linked list */ 1702 /* get a random message for the 'book' from linked list */
1722 if (nrofmsg > 1) 1703 if (nrofmsg > 1)
1723 { 1704 {
1724 msg = first_msg; 1705 msg = first_msg;
1725 msgnum = RANDOM () % nrofmsg; 1706 msgnum = RANDOM () % nrofmsg;
1726 for (i = 0; msg && i < nrofmsg && i != msgnum; i++) 1707 for (i = 0; msg && i < nrofmsg && i != msgnum; i++)
1727 msg = msg->next; 1708 msg = msg->next;
1728 } 1709 }
1729 1710
1730 if (msg && !book_overflow (retbuf, msg->name, booksize)) 1711 if (msg && !book_overflow (retbuf, msg->name, booksize))
1731 strcpy (retbuf, msg->name); 1712 strcpy (retbuf, msg->name);
1732 else 1713 else
1733 sprintf (retbuf, "\n <undecipherable text>"); 1714 sprintf (retbuf, "\n <undecipherable text>");
1734 1715
1735#ifdef BOOK_MSG_DEBUG 1716#ifdef BOOK_MSG_DEBUG
1736 LOG (llevDebug, "\n info_list_msg() created strng: %d\n", strlen (retbuf)); 1717 LOG (llevDebug, "\n info_list_msg() created strng: %d\n", strlen (retbuf));
1737 LOG (llevDebug, " MADE THIS:\n%s\n", retbuf); 1718 LOG (llevDebug, " MADE THIS:\n%s\n", retbuf);
1738#endif 1719#endif
1754 int i; 1735 int i;
1755 size_t introlen; 1736 size_t introlen;
1756 object *god = pntr_to_god_obj (get_rand_god ()); 1737 object *god = pntr_to_god_obj (get_rand_god ());
1757 1738
1758 if (!god) 1739 if (!god)
1759 return (char *) NULL; /* oops, problems... */ 1740 return (char *) NULL; /* oops, problems... */
1760 name = god->name; 1741 name = god->name;
1761 1742
1762 /* preamble.. */ 1743 /* preamble.. */
1763 sprintf (retbuf, "This document contains knowledge concerning\n"); 1744 sprintf (retbuf, "This document contains knowledge concerning\n");
1764 sprintf (retbuf, "%sthe diety %s", retbuf, name); 1745 sprintf (retbuf, "%sthe diety %s", retbuf, name);
1765 1746
1766 /* Always have as default information the god's descriptive terms. */ 1747 /* Always have as default information the god's descriptive terms. */
1767 if (nstrtok (god->msg, ",") > 0) 1748 if (nstrtok (god->msg, ",") > 0)
1768 { 1749 {
1769 strcat (retbuf, ", known as"); 1750 strcat (retbuf, ", known as");
1770 strcat (retbuf, strtoktolin (god->msg, ",")); 1751 strcat (retbuf, strtoktolin (god->msg, ","));
1771 } 1752 }
1772 else 1753 else
1773 strcat (retbuf, "..."); 1754 strcat (retbuf, "...");
1774 1755
1775 strcat (retbuf, "\n ---\n"); 1756 strcat (retbuf, "\n ---\n");
1776 introlen = strlen (retbuf); /* so we will know if no new info is added later */ 1757 introlen = strlen (retbuf); /* so we will know if no new info is added later */
1777 1758
1778 /* Information about the god is random, and based on the level of the 1759 /* Information about the god is random, and based on the level of the
1780 * this ... 1761 * this ...
1781 */ 1762 */
1782 1763
1783 while (level > 0) 1764 while (level > 0)
1784 { 1765 {
1785 sprintf (buf, " "); 1766 sprintf (buf, " ");
1786 if (level == 2 && RANDOM () % 2) 1767 if (level == 2 && RANDOM () % 2)
1787 { /* enemy god */ 1768 { /* enemy god */
1788 const char *enemy = god->title; 1769 const char *enemy = god->title;
1789 if (enemy) 1770 if (enemy)
1790 sprintf (buf, "The gods %s and %s are enemies.\n ---\n", 1771 sprintf (buf, "The gods %s and %s are enemies.\n ---\n",
1791 name, enemy); 1772 name, enemy);
1792 } 1773 }
1793 if (level == 3 && RANDOM () % 2) 1774 if (level == 3 && RANDOM () % 2)
1794 { /* enemy race, what the god's holy word effects */ 1775 { /* enemy race, what the god's holy word effects */
1795 const char *enemy = god->slaying; 1776 const char *enemy = god->slaying;
1796 if (enemy && !(god->path_denied & PATH_TURNING)) 1777 if (enemy && !(god->path_denied & PATH_TURNING))
1797 if ((i = nstrtok (enemy, ",")) > 0) 1778 if ((i = nstrtok (enemy, ",")) > 0)
1798 { 1779 {
1799 char tmpbuf[MAX_BUF]; 1780 char tmpbuf[MAX_BUF];
1800 sprintf (buf, "The holy words of %s have the power to\n", name); 1781 sprintf (buf, "The holy words of %s have the power to\n", name);
1801 strcat (buf, "slay creatures belonging to the "); 1782 strcat (buf, "slay creatures belonging to the ");
1802 if (i > 1) 1783 if (i > 1)
1803 sprintf (tmpbuf, "following \n races:%s", 1784 sprintf (tmpbuf, "following \n races:%s",
1804 strtoktolin (enemy, ",")); 1785 strtoktolin (enemy, ","));
1805 else 1786 else
1806 sprintf (tmpbuf, "race of%s", strtoktolin (enemy, ",")); 1787 sprintf (tmpbuf, "race of%s", strtoktolin (enemy, ","));
1807 sprintf (buf, "%s%s\n ---\n", buf, tmpbuf); 1788 sprintf (buf, "%s%s\n ---\n", buf, tmpbuf);
1808 } 1789 }
1809 } 1790 }
1810 if (level == 4 && RANDOM () % 2) 1791 if (level == 4 && RANDOM () % 2)
1811 { /* Priest of god gets these protect,vulnerable... */ 1792 { /* Priest of god gets these protect,vulnerable... */
1812 char tmpbuf[MAX_BUF],*cp; 1793 char tmpbuf[MAX_BUF],*cp;
1813 1794
1814 cp = describe_resistance(god, 1); 1795 cp = describe_resistance(god, 1);
1815 1796
1816 if (*cp) { /* This god does have protections */ 1797 if (*cp) { /* This god does have protections */
1817 sprintf (tmpbuf, "%s has a potent aura which is extended\n" 1798 sprintf (tmpbuf, "%s has a potent aura which is extended\n"
1818 ,name); 1799 ,name);
1819 strcat (tmpbuf, "faithful priests. The effects of this aura include:\n"); 1800 strcat (tmpbuf, "faithful priests. The effects of this aura include:\n");
1820 strcat(tmpbuf, cp); 1801 strcat(tmpbuf, cp);
1821 strcat (buf, tmpbuf); 1802 strcat (buf, tmpbuf);
1822 strcat (buf, "\n ---\n"); 1803 strcat (buf, "\n ---\n");
1823 } 1804 }
1824 else 1805 else
1825 sprintf (buf, " "); 1806 sprintf (buf, " ");
1826 } 1807 }
1827 if (level == 5 && RANDOM () % 2) 1808 if (level == 5 && RANDOM () % 2)
1828 { /* aligned race, summoning */ 1809 { /* aligned race, summoning */
1829 const char *race = god->race; /* aligned race */ 1810 const char *race = god->race; /* aligned race */
1830 if (race && !(god->path_denied & PATH_SUMMON)) 1811 if (race && !(god->path_denied & PATH_SUMMON))
1831 if ((i = nstrtok (race, ",")) > 0) 1812 if ((i = nstrtok (race, ",")) > 0)
1832 { 1813 {
1833 char tmpbuf[MAX_BUF]; 1814 char tmpbuf[MAX_BUF];
1834 sprintf (buf, "Creatures sacred to %s include the \n", name); 1815 sprintf (buf, "Creatures sacred to %s include the \n", name);
1835 if (i > 1) 1816 if (i > 1)
1836 sprintf (tmpbuf, "following \n races:%s", 1817 sprintf (tmpbuf, "following \n races:%s",
1837 strtoktolin (race, ",")); 1818 strtoktolin (race, ","));
1838 else 1819 else
1839 sprintf (tmpbuf, "race of%s", strtoktolin (race, ",")); 1820 sprintf (tmpbuf, "race of%s", strtoktolin (race, ","));
1840 sprintf (buf, "%s%s\n ---\n", buf, tmpbuf); 1821 sprintf (buf, "%s%s\n ---\n", buf, tmpbuf);
1841 } 1822 }
1842 } 1823 }
1843 if (level == 6 && RANDOM () % 2) 1824 if (level == 6 && RANDOM () % 2)
1844 { /* blessing,curse properties of the god */ 1825 { /* blessing,curse properties of the god */
1845 char tmpbuf[MAX_BUF],*cp; 1826 char tmpbuf[MAX_BUF],*cp;
1846 1827
1847 cp = describe_resistance(god, 1); 1828 cp = describe_resistance(god, 1);
1848 1829
1849 if (*cp) { /* This god does have protections */ 1830 if (*cp) { /* This god does have protections */
1850 sprintf (tmpbuf, "\nThe priests of %s are known to be able to \n" 1831 sprintf (tmpbuf, "\nThe priests of %s are known to be able to \n"
1851 ,name); 1832 ,name);
1852 strcat (tmpbuf, "bestow a blessing which makes the recipient\n"); 1833 strcat (tmpbuf, "bestow a blessing which makes the recipient\n");
1853 strcat(tmpbuf, cp); 1834 strcat(tmpbuf, cp);
1854 strcat (buf, tmpbuf); 1835 strcat (buf, tmpbuf);
1855 strcat (buf, "\n ---\n"); 1836 strcat (buf, "\n ---\n");
1856 } 1837 }
1857 else 1838 else
1858 sprintf (buf, " "); 1839 sprintf (buf, " ");
1859 1840
1860 } 1841 }
1861 if (level == 8 && RANDOM () % 2) 1842 if (level == 8 && RANDOM () % 2)
1862 { /* immunity, holy possession */ 1843 { /* immunity, holy possession */
1863 int has_effect = 0, tmpvar; 1844 int has_effect = 0, tmpvar;
1864 char tmpbuf[MAX_BUF]; 1845 char tmpbuf[MAX_BUF];
1865 sprintf (tmpbuf, "\n"); 1846 sprintf (tmpbuf, "\n");
1866 sprintf (tmpbuf, "The priests of %s are known to make cast a mighty \n" 1847 sprintf (tmpbuf, "The priests of %s are known to make cast a mighty \n"
1867 ,name); 1848 ,name);
1868 1849
1869 strcat (tmpbuf, "prayer of possession which gives the recipient\n"); 1850 strcat (tmpbuf, "prayer of possession which gives the recipient\n");
1870 1851
1871 for (tmpvar=0; tmpvar<NROFATTACKS; tmpvar++) { 1852 for (tmpvar=0; tmpvar<NROFATTACKS; tmpvar++) {
1872 if (god->resist[tmpvar]==100) { 1853 if (god->resist[tmpvar]==100) {
1873 has_effect = 1; 1854 has_effect = 1;
1874 sprintf(tmpbuf + strlen(tmpbuf),"Immunity to %s", attacktype_desc[tmpvar]); 1855 sprintf(tmpbuf + strlen(tmpbuf),"Immunity to %s", attacktype_desc[tmpvar]);
1875 } 1856 }
1876 } 1857 }
1877 if (has_effect) { 1858 if (has_effect) {
1878 strcat (buf, tmpbuf); 1859 strcat (buf, tmpbuf);
1879 strcat (buf, "\n ---\n"); 1860 strcat (buf, "\n ---\n");
1880 } 1861 }
1881 else 1862 else
1882 sprintf (buf, " "); 1863 sprintf (buf, " ");
1883 } 1864 }
1884 if (level == 12 && RANDOM () % 2) 1865 if (level == 12 && RANDOM () % 2)
1885 { /* spell paths */ 1866 { /* spell paths */
1886 int has_effect = 0, tmpvar; 1867 int has_effect = 0, tmpvar;
1887 char tmpbuf[MAX_BUF]; 1868 char tmpbuf[MAX_BUF];
1888 sprintf (tmpbuf, "\n"); 1869 sprintf (tmpbuf, "\n");
1889 sprintf (tmpbuf, "It is rarely known fact that the priests of %s\n" 1870 sprintf (tmpbuf, "It is rarely known fact that the priests of %s\n"
1890 ,name); 1871 ,name);
1891 strcat (tmpbuf, "are mystically transformed. Effects of this include:\n"); 1872 strcat (tmpbuf, "are mystically transformed. Effects of this include:\n");
1892 if ((tmpvar = god->path_attuned)) 1873 if ((tmpvar = god->path_attuned))
1893 { 1874 {
1894 has_effect = 1; 1875 has_effect = 1;
1895 DESCRIBE_PATH (tmpbuf, tmpvar, "Attuned"); 1876 DESCRIBE_PATH (tmpbuf, tmpvar, "Attuned");
1896 } 1877 }
1897 if ((tmpvar = god->path_repelled)) 1878 if ((tmpvar = god->path_repelled))
1898 { 1879 {
1899 has_effect = 1; 1880 has_effect = 1;
1900 DESCRIBE_PATH (tmpbuf, tmpvar, "Repelled"); 1881 DESCRIBE_PATH (tmpbuf, tmpvar, "Repelled");
1901 } 1882 }
1902 if ((tmpvar = god->path_denied)) 1883 if ((tmpvar = god->path_denied))
1903 { 1884 {
1904 has_effect = 1; 1885 has_effect = 1;
1905 DESCRIBE_PATH (tmpbuf, tmpvar, "Denied"); 1886 DESCRIBE_PATH (tmpbuf, tmpvar, "Denied");
1906 } 1887 }
1907 if (has_effect) 1888 if (has_effect)
1908 { 1889 {
1909 strcat (buf, tmpbuf); 1890 strcat (buf, tmpbuf);
1910 strcat (buf, "\n ---\n"); 1891 strcat (buf, "\n ---\n");
1911 } 1892 }
1912 else 1893 else
1913 sprintf (buf, " "); 1894 sprintf (buf, " ");
1914 } 1895 }
1915 1896
1916 /* check to be sure new buffer size dont exceed either 1897 /* check to be sure new buffer size dont exceed either
1917 * the maximum buffer size, or the 'natural' size of the 1898 * the maximum buffer size, or the 'natural' size of the
1918 * book... 1899 * book...
1919 */ 1900 */
1920 if (book_overflow (retbuf, buf, booksize)) 1901 if (book_overflow (retbuf, buf, booksize))
1921 break; 1902 break;
1922 else if (strlen (buf) > 1) 1903 else if (strlen (buf) > 1)
1923 strcat (retbuf, buf); 1904 strcat (retbuf, buf);
1924 level--; 1905 level--;
1925 } 1906 }
1926 if (strlen (retbuf) == introlen) 1907 if (strlen (retbuf) == introlen)
1927 { /* we got no information beyond the preamble! */ 1908 { /* we got no information beyond the preamble! */
1928 strcat (retbuf, " [Unfortunately the rest of the information is\n"); 1909 strcat (retbuf, " [Unfortunately the rest of the information is\n");
1929 strcat (retbuf, " hopelessly garbled!]\n ---\n"); 1910 strcat (retbuf, " hopelessly garbled!]\n ---\n");
1930 } 1911 }
1931#ifdef BOOK_MSG_DEBUG 1912#ifdef BOOK_MSG_DEBUG
1932 LOG (llevDebug, "\n god_info_msg() created strng: %d\n", strlen (retbuf)); 1913 LOG (llevDebug, "\n god_info_msg() created strng: %d\n", strlen (retbuf));
1933 fprintf (logfile, " MADE THIS:\n%s", retbuf); 1914 fprintf (logfile, " MADE THIS:\n%s", retbuf);
1934#endif 1915#endif
1959 int level = book->level ? (RANDOM () % book->level) + 1 : 1; 1940 int level = book->level ? (RANDOM () % book->level) + 1 : 1;
1960 int book_buf_size; 1941 int book_buf_size;
1961 1942
1962 /* safety */ 1943 /* safety */
1963 if (book->type != BOOK) 1944 if (book->type != BOOK)
1964 return; 1945 return;
1965 1946
1966 if (level <= 0) 1947 if (level <= 0)
1967 return; /* if no level no point in doing any more... */ 1948 return; /* if no level no point in doing any more... */
1968 1949
1969 /* Max text length this book can have. */ 1950 /* Max text length this book can have. */
1970 book_buf_size = BOOKSIZE (book); 1951 book_buf_size = BOOKSIZE (book);
1971 1952
1972 /* &&& The message switch &&& */ 1953 /* &&& The message switch &&& */
1983 1964
1984 msg_type = msg_type > 0 ? msg_type : (RANDOM () % 6); 1965 msg_type = msg_type > 0 ? msg_type : (RANDOM () % 6);
1985 switch (msg_type) 1966 switch (msg_type)
1986 { 1967 {
1987 case 1: /* monster attrib */ 1968 case 1: /* monster attrib */
1988 strcpy (msgbuf, mon_info_msg (level, book_buf_size)); 1969 strcpy (msgbuf, mon_info_msg (level, book_buf_size));
1989 break; 1970 break;
1990 case 2: /* artifact attrib */ 1971 case 2: /* artifact attrib */
1991 strcpy (msgbuf, artifact_msg (level, book_buf_size)); 1972 strcpy (msgbuf, artifact_msg (level, book_buf_size));
1992 break; 1973 break;
1993 case 3: /* grouping incantations/prayers by path */ 1974 case 3: /* grouping incantations/prayers by path */
1994 strcpy (msgbuf, spellpath_msg (level, book_buf_size)); 1975 strcpy (msgbuf, spellpath_msg (level, book_buf_size));
1995 break; 1976 break;
1996 case 4: /* describe an alchemy formula */ 1977 case 4: /* describe an alchemy formula */
1997 make_formula_book(book, level); 1978 make_formula_book(book, level);
1998 /* make_formula_book already gives title */ 1979 /* make_formula_book already gives title */
1999 return; 1980 return;
2000 break; 1981 break;
2001 case 5: /* bits of information about a god */ 1982 case 5: /* bits of information about a god */
2002 strcpy (msgbuf, god_info_msg (level, book_buf_size)); 1983 strcpy (msgbuf, god_info_msg (level, book_buf_size));
2003 break; 1984 break;
2004 case 0: /* use info list in lib/ */ 1985 case 0: /* use info list in lib/ */
2005 default: 1986 default:
2006 strcpy (msgbuf, msgfile_msg (level, book_buf_size)); 1987 strcpy (msgbuf, msgfile_msg (level, book_buf_size));
2007 break; 1988 break;
2008 } 1989 }
2009 1990
2010 strcat (msgbuf, "\n"); /* safety -- we get ugly map saves/crashes w/o this */ 1991 strcat (msgbuf, "\n"); /* safety -- we get ugly map saves/crashes w/o this */
2011 if (strlen (msgbuf) > 1) 1992 if (strlen (msgbuf) > 1)
2012 { 1993 {
2013 if (book->msg) 1994 book->msg = msgbuf;
2014 free_string (book->msg);
2015 book->msg = add_string (msgbuf);
2016 /* lets give the "book" a new name, which may be a compound word */ 1995 /* lets give the "book" a new name, which may be a compound word */
2017 change_book (book, msg_type); 1996 change_book (book, msg_type);
2018 } 1997 }
2019 1998
2020} 1999}
2021 2000
2022 2001
2036 2015
2037 LOG (llevDebug, "freeing all book information\n"); 2016 LOG (llevDebug, "freeing all book information\n");
2038 2017
2039 for (tlist = booklist; tlist != NULL; tlist = tnext) 2018 for (tlist = booklist; tlist != NULL; tlist = tnext)
2040 { 2019 {
2041 tnext = tlist->next; 2020 tnext = tlist->next;
2021
2042 for (title1 = tlist->first_book; title1; title1 = titlenext) 2022 for (title1 = tlist->first_book; title1; title1 = titlenext)
2043 { 2023 {
2044 titlenext = title1->next; 2024 titlenext = title1->next;
2045 if (title1->name) 2025 delete title1;
2046 free_string (title1->name); 2026 }
2047 if (title1->authour) 2027
2048 free_string (title1->authour); 2028 delete tlist;
2049 if (title1->archname)
2050 free_string (title1->archname);
2051 free (title1);
2052 }
2053 free (tlist);
2054 } 2029 }
2055 for (lmsg = first_msg; lmsg; lmsg = nextmsg) 2030 for (lmsg = first_msg; lmsg; lmsg = nextmsg)
2056 { 2031 {
2057 nextmsg = lmsg->next; 2032 nextmsg = lmsg->next;
2058 if (lmsg->name) 2033 delete lmsg;
2059 free_string (lmsg->name);
2060 free (lmsg);
2061 } 2034 }
2062 for (monlink = first_mon_info; monlink; monlink = nextmon) 2035 for (monlink = first_mon_info; monlink; monlink = nextmon)
2063 { 2036 {
2064 nextmon = monlink->next; 2037 nextmon = monlink->next;
2065 free (monlink); 2038 free (monlink);
2066 } 2039 }
2067} 2040}
2068 2041
2069 2042
2070/***************************************************************************** 2043/*****************************************************************************
2091 sprintf (fname, "%s/bookarch", settings.localdir); 2064 sprintf (fname, "%s/bookarch", settings.localdir);
2092 LOG (llevDebug, "Updating book archive: %s...\n", fname); 2065 LOG (llevDebug, "Updating book archive: %s...\n", fname);
2093 2066
2094 if ((fp = fopen (fname, "w")) == NULL) 2067 if ((fp = fopen (fname, "w")) == NULL)
2095 { 2068 {
2096 LOG (llevDebug, "Can't open book archive file %s\n", fname); 2069 LOG (llevDebug, "Can't open book archive file %s\n", fname);
2097 } 2070 }
2098 else 2071 else
2099 { 2072 {
2100 while (bl) 2073 while (bl)
2101 { 2074 {
2102 for (book = bl->first_book; book; book = book->next) 2075 for (book = bl->first_book; book; book = book->next)
2103 if (book && book->authour) 2076 if (book && book->authour)
2104 { 2077 {
2105 fprintf (fp, "title %s\n", book->name); 2078 fprintf (fp, "title %s\n", &book->name);
2106 fprintf (fp, "authour %s\n", book->authour); 2079 fprintf (fp, "authour %s\n", &book->authour);
2107 fprintf (fp, "arch %s\n", book->archname); 2080 fprintf (fp, "arch %s\n", &book->archname);
2108 fprintf (fp, "level %d\n", book->level); 2081 fprintf (fp, "level %d\n", book->level);
2109 fprintf (fp, "type %d\n", index); 2082 fprintf (fp, "type %d\n", index);
2110 fprintf (fp, "size %d\n", book->size); 2083 fprintf (fp, "size %d\n", book->size);
2111 fprintf (fp, "index %d\n", book->msg_index); 2084 fprintf (fp, "index %d\n", book->msg_index);
2112 fprintf (fp, "end\n"); 2085 fprintf (fp, "end\n");
2113 } 2086 }
2114 bl = bl->next; 2087 bl = bl->next;
2115 index++; 2088 index++;
2116 } 2089 }
2117 fclose (fp); 2090 fclose (fp);
2118 chmod (fname, SAVE_MODE); 2091 chmod (fname, SAVE_MODE);
2119 } 2092 }
2120} 2093}
2121readable_message_type* get_readable_message_type(object* readable){ 2094readable_message_type* get_readable_message_type(object* readable){
2122 uint8 subtype = readable->subtype; 2095 uint8 subtype = readable->subtype;
2123 if (subtype>last_readable_subtype) 2096 if (subtype>last_readable_subtype)
2124 return &(readable_message_types[0]); 2097 return &(readable_message_types[0]);
2125 return &(readable_message_types[subtype]); 2098 return &(readable_message_types[subtype]);
2126} 2099}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines