Go to the documentation of this file.
75 #define MAX_TITLE_CHECK 20
80 #define MSGTYPE_MONSTER 1
82 #define MSGTYPE_ARTIFACT 2
84 #define MSGTYPE_SPELLPATH 3
86 #define MSGTYPE_ALCHEMY 4
88 #define MSGTYPE_GODS 5
90 #define MSGTYPE_MSGFILE 6
97 #define arraysize(arrayname) (sizeof(arrayname)/sizeof(*(arrayname)))
218 {
"Missile Weapon",
BOW },
219 {
"Missile",
ARROW },
220 {
"Hand Weapon",
WEAPON },
221 {
"Artifact",
SKILL },
347 "magical manufacture",
349 "philosophical items",
611 LOG(
llevInfo,
"Warning: invalid book index %d, using 0 instead\n", i);
615 for (tl =
booklist, number = i; tl && number; tl = tl->
next, number--) {
637 int nstrtok(
const char *buf1,
const char *buf2) {
645 for (tbuf = strtok(
buf, buf2); tbuf; tbuf = strtok(NULL, buf2)) {
657 while ((*
buf) ==
' ') {
679 char *
strtoktolin(
const char *buf1,
const char *buf2,
char *retbuf,
size_t size) {
680 int maxi, i =
nstrtok(buf1, buf2);
685 snprintf(retbuf, size,
" ");
686 for (tbuf = strtok(
buf, buf2); tbuf && i > 0; tbuf = strtok(NULL, buf2)) {
687 snprintf(retbuf+strlen(retbuf), size-strlen(retbuf),
"%s",
trim(tbuf));
689 if (i == 1 && maxi > 1)
690 snprintf(retbuf+strlen(retbuf), size-strlen(retbuf),
" and ");
691 else if (i > 0 && maxi > 1)
692 snprintf(retbuf+strlen(retbuf), size-strlen(retbuf),
", ");
694 snprintf(retbuf+strlen(retbuf), size-strlen(retbuf),
".");
730 #ifdef BOOK_MSG_DEBUG
734 static int did_init_barch = 0;
744 LOG(
llevDebug,
" Reading bookarch from %s...\n", fname);
746 fp = fopen(fname,
"r");
758 for (lineno = 1; fgets(
buf,
MAX_BUF, fp) != NULL; lineno++) {
764 cp = strchr(
buf,
'\n');
766 while (cp >
buf && (cp[-1] ==
' ' || cp[-1] ==
'\t'))
771 if (strncmp(
buf,
"title ", 6) == 0) {
774 while (*cp ==
' ' || *cp ==
'\t')
777 LOG(
llevInfo,
"Warning: missing book title at %s, line %d\n", fname, lineno);
783 #ifdef BOOK_MSG_DEBUG
787 }
else if (book == NULL) {
790 LOG(
llevInfo,
"Warning: expecting 'title' at %s, line %d\n", fname, lineno);
792 }
else if (strncmp(
buf,
"authour ", 8) == 0) {
794 while (*cp ==
' ' || *cp ==
'\t')
797 LOG(
llevInfo,
"Warning: missing book authour at %s, line %d\n", fname, lineno);
801 }
else if (strncmp(
buf,
"arch ", 5) == 0) {
803 while (*cp ==
' ' || *cp ==
'\t')
806 LOG(
llevInfo,
"Warning: missing book arch at %s, line %d\n", fname, lineno);
810 }
else if (sscanf(
buf,
"level %d%n", &
value, &len) == 1 && len == (
int)strlen(
buf)) {
812 }
else if (sscanf(
buf,
"type %d%n", &
value, &len) == 1 && len == (
int)strlen(
buf)) {
814 }
else if (sscanf(
buf,
"size %d%n", &
value, &len) == 1 && len == (
int)strlen(
buf)) {
816 }
else if (sscanf(
buf,
"index %d%n", &
value, &len) == 1 && len == (
int)strlen(
buf)) {
818 }
else if (strcmp(
buf,
"end") == 0) {
823 LOG(
llevInfo,
"Warning: syntax error at %s, line %d\n", fname, lineno);
827 LOG(
llevInfo,
"Warning: missing 'end' at %s, line %d\n", fname, lineno);
837 #ifdef BOOK_MSG_DEBUG
838 LOG(
llevDebug,
"\n init_book_archive() got %d titles.\n", nroftitle);
854 LOG(
llevInfo,
"Warning: book with no type at %s, line %d; using type 0\n", fname, lineno);
886 static int did_init_mon_info = 0;
888 if (did_init_mon_info)
890 did_init_mon_info = 1;
904 static int did_this = 0;
941 return (
title *)NULL;
945 return (
title *)NULL;
947 length = strlen(book->
msg);
950 if (
t->size == length &&
t->msg_index ==
index) {
952 LOG(
llevDebug,
"Found title match (list %d): %s %s (%d)\n", msgtype,
t->name,
t->authour,
t->msg_index);
957 return (
title *)NULL;
1002 if (book->
weight > 2000) {
1026 if (msgtype < 0 || strlen(
op->msg) < 5)
1099 LOG(
llevError,
"add_book_to_list can't get booklist!\n");
1106 t->size = strlen(book->
msg);
1118 #ifdef ARCHIVE_DEBUG
1142 LOG(
llevError,
"change_book_name() called w/ illegal obj type.\n");
1175 const char *old_title;
1176 const char *old_name;
1186 LOG(
llevError,
"change_book_name(): can't find title list\n");
1191 if (numb == maxnames) {
1192 #ifdef ARCHIVE_DEBUG
1193 LOG(
llevDebug,
"titles for list %d full (%d possible).\n", msgtype, maxnames);
1195 if (old_title != NULL)
1219 #ifdef ARCHIVE_DEBUG
1220 LOG(
llevDebug,
"Failed to obtain unique title for %s %s (names:%d/%d)\n", book->
name, book->
title, numb, maxnames);
1236 }
else if (book->
title && strlen(book->
msg) > 5) {
1240 if (old_title != NULL)
1274 return (
object *)NULL;
1285 LOG(
llevError,
"get_random_mon: Didn't find a monster when we should have\n");
1309 LOG(
llevError,
"get_random_mon() couldn't return monster for level %d\n",
level);
1318 LOG(
llevError,
"get_random_mon(): didn't find a monster when we should have\n");
1382 const char *sep =
":";
1460 if (
temp->name[0] ==
'!')
1486 else if (chance >= 10)
1488 else if (chance >= 5)
1537 if (book_entries > 5)
1551 }
while (al == NULL && i < 10);
1574 while (book_entries > 0) {
1690 int chance,
count = 0;
1691 const char *op_name;
1712 for (formula = fl->
items; formula != NULL; formula = formula->
next) {
1713 chance -= formula->
chance;
1714 if (chance <= 0 && formula->chance != 0 && !formula->
is_combination)
1732 LOG(
llevError,
"formula_msg() can't find arch %s for formula.\n", op_name);
1747 if (strcmp(formula->
title,
"NONE")) {
1773 if (formula->
ingred != NULL) {
1782 snprintf(
name,
sizeof(
name),
"an unknown place");
1791 LOG(
llevError,
"formula_msg() no ingredient list for object %s of %s\n", op_name, formula->
title);
1801 snprintf(km,
sizeof(km),
"alchemy:%d:%d:%s",
count, formula->
index, formula->
title);
1822 if (
msg->identifier != NULL) {
1826 snprintf(km,
sizeof(km),
"message:%s",
msg->identifier);
1829 if (
msg->quest_code) {
1867 LOG(
llevError,
"common/readable.c:god_info_msg() - passed in booksize (%lu) is larger than book buffer (%d)\n", (
unsigned long)
booksize,
BOOK_BUF);
1901 snprintf(
buf,
sizeof(
buf),
"god:%s:%d", god->
name, what);
1930 size_t book_buf_size;
1942 book_buf_size -= strlen(
"\n");
1960 msg_type = msg_type > 0 ? msg_type : (
int)(
RANDOM()%6);
2012 title *title1, *titlenext;
2017 for (tlist =
booklist; tlist != NULL; tlist = tnext) {
2018 tnext = tlist->
next;
2019 for (title1 = tlist->
first_book; title1; title1 = titlenext) {
2020 titlenext = title1->
next;
2032 nextmon = monlink->
next;
2059 LOG(
llevDebug,
"Updating book archive: %s...\n", fname);
2068 fprintf(fp,
"title %s\n", book->
name);
2069 fprintf(fp,
"authour %s\n", book->
authour);
2070 fprintf(fp,
"arch %s\n", book->
archname);
2071 fprintf(fp,
"level %d\n", book->
level);
2072 fprintf(fp,
"type %d\n",
index);
2074 fprintf(fp,
"size %lu\n", (
unsigned long)book->
size);
2075 fprintf(fp,
"index %d\n", book->
msg_index);
2076 fprintf(fp,
"end\n");
2083 LOG(
llevError,
"Could not set permissions on '%s'\n", fname);
2097 uint8_t subtype = readable->
subtype;
#define MSG_TYPE_MONUMENT_WALL_2
static const readable_message_type readable_message_types[]
static int need_to_write_bookarchive
#define MSG_TYPE_BOOK_SPELL_PRAYER
static const char *const book_author[]
recipelist * get_formulalist(int i)
sstring add_string(const char *str)
static void init_book_archive(void)
StringBuffer * stringbuffer_new(void)
#define MSG_TYPE_PAPER_LETTER_OLD_2
#define MSG_TYPE_BOOK_SPELL_SUMMONER
#define MONSTER_EXCLUDE_FROM_READABLE_KEY
static const uint32_t spellpathdef[NRSPELLPATHS]
static const char *const formula_author[]
#define QUERY_FLAG(xyz, p)
static title * get_empty_book(void)
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
void archetypes_for_each(arch_op op)
#define MSGTYPE_SPELLPATH
static void do_spellpath_msg(archetype *at)
object * object_new(void)
#define MSG_TYPE_PAPER_LETTER_NEW_2
static void add_author(object *op, int msgtype)
#define MSG_TYPE_BOOK_QUARTO_1
#define MSG_TYPE_SIGN_BASIC
static StringBuffer * god_info_msg(int level, size_t booksize, object *book)
static struct @0 sp_params
static const char *const gods_book_name[]
GeneralMessage * get_random_message()
#define MSG_TYPE_PAPER_SCROLL_NEW_2
const char * trim(const char *buf)
#define MSG_TYPE_PAPER_SCROLL_OLD_2
#define MSG_TYPE_PAPER_NOTE_2
#define MSG_TYPE_CARD_MONEY_2
#define MSG_TYPE_MONUMENT_STATUE_3
#define MSG_TYPE_PAPER_LETTER_OLD_1
#define MSG_TYPE_SIGN_DIR_RIGHT
static titlelist * get_empty_booklist(void)
static int unique_book(const object *book, int msgtype)
#define MSG_TYPE_CARD_SIMPLE_2
static void add_book_to_list(const object *book, int msgtype)
struct artifactstruct * items
static const char *const formula_book_name[]
#define MSG_TYPE_BOOK_CLASP_2
static void add_book(title *book, int type, const char *fname, int lineno)
#define MSG_TYPE_BOOK_ELEGANT_1
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
static title * find_title(const object *book, int msgtype)
sstring get_message_body(const GeneralMessage *message)
static StringBuffer * mon_desc(const object *mon)
static titlelist * booklist
int nstrtok(const char *buf1, const char *buf2)
static const arttypename art_name_array[]
static StringBuffer * artifact_msg(unsigned int level, size_t booksize)
#define MSG_TYPE_PAPER_SCROLL_OLD_1
const char * object_get_value(const object *op, const char *const key)
#define MSG_TYPE_CARD_STRANGE_1
void free_string(sstring str)
int strtoint(const char *buf)
static const char *const light_book_name[]
static object * get_next_mon(const object *tmp)
char * strtoktolin(const char *buf1, const char *buf2, char *retbuf, size_t size)
static StringBuffer * artifact_describe(const artifact *art, const artifactlist *al, int message, int art_name, int separator)
const object * get_rand_god(void)
const readable_message_type * get_readable_message_type(object *readable)
#define MSG_TYPE_MONUMENT_GRAVESTONE_1
#define MSG_TYPE_MONUMENT
artifactlist * find_artifactlist(int type)
static titlelist * get_titlelist(int i)
struct titlestruct * first_book
void object_copy(const object *src_ob, object *dest_ob)
#define MSG_TYPE_CARD_STRANGE_2
#define MSG_TYPE_SIGN_DIR_BOTH
void query_name(const object *op, char *buf, size_t size)
#define MSG_TYPE_MONUMENT_GRAVESTONE_2
sstring stringbuffer_finish_shared(StringBuffer *sb)
int of_close(OutputFile *of)
#define MSG_TYPE_SIGN_DIR_LEFT
struct titleliststruct titlelist
struct artifactstruct * next
#define MSG_TYPE_BOOK_CLASP_1
void fatal(enum fatal_error err)
void stringbuffer_append_string(StringBuffer *sb, const char *str)
static const int max_titles[6]
#define FREE_AND_COPY(sv, nv)
#define MSG_TYPE_MONUMENT_STATUE_2
#define MSG_TYPE_CARD_ELEGANT_1
static const char *const path_book_name[]
object * object_create_arch(archetype *at)
char * stringbuffer_finish(StringBuffer *sb)
int buf_overflow(const char *buf1, const char *buf2, size_t bufsize)
static void do_monster(archetype *at)
int object_set_value(object *op, const char *key, const char *value, int add_key)
const typedef char * sstring
#define FLAG_UNAGGRESSIVE
#define MSG_TYPE_CARD_ELEGANT_3
#define MSG_TYPE_CARD_MONEY_3
static const char *const mon_book_name[]
static const int last_readable_subtype
#define MSG_TYPE_BOOK_SPELL_EVOKER
#define MSG_TYPE_MONUMENT_GRAVESTONE_3
#define MSG_TYPE_MONUMENT_STONE_3
#define MSG_TYPE_MONUMENT_WALL_3
#define MSG_TYPE_PAPER_ENVELOPE_2
#define MSG_TYPE_CARD_ELEGANT_2
#define MSG_TYPE_PAPER_NOTE_1
#define MSG_TYPE_BOOK_SPELL_SORCERER
#define MSG_TYPE_BOOK_SPELL_PYRO
#define MSG_TYPE_SIGN_MAGIC_MOUTH
size_t strlcpy(char *dst, const char *src, size_t size)
#define arraysize(arrayname)
object * get_random_mon(int level)
const Face * get_message_face(const GeneralMessage *message)
void add_abilities(object *op, const object *change)
object * create_archetype(const char *name)
static void make_formula_book(object *book, int level)
static const char *const book_descrpt[]
void object_set_msg(object *op, const char *msg)
#define MSG_TYPE_CARD_MONEY_1
void tailor_readable_ob(object *book, int msg_type)
void write_book_archive(void)
struct titlestruct * next
archetype * find_archetype_by_object_name(const char *name)
#define MSG_TYPE_PAPER_ENVELOPE_1
const char *const spellpathnames[NRSPELLPATHS]
static const char *const mon_author[]
#define MSG_TYPE_CARD_SIMPLE_3
struct namebytype arttypename
void LOG(LogLevel logLevel, const char *format,...)
FILE * of_open(OutputFile *of, const char *fname)
#define MSG_TYPE_PAPER_LETTER_NEW_1
static const char *const heavy_book_name[]
archetype * find_archetype(const char *name)
#define MSG_TYPE_BOOK_ELEGANT_2
static void change_book(object *book, int msgtype)
size_t stringbuffer_length(StringBuffer *sb)
static void init_mon_info(void)
static StringBuffer * msgfile_msg(object *book, size_t booksize)
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
struct recipestruct * next
#define MSG_TYPE_MONUMENT_STONE_2
object * object_insert_in_ob(object *op, object *where)
static const char *const path_author[]
static StringBuffer * spellpath_msg(int level, size_t booksize, StringBuffer *buf)
#define MSG_TYPE_MONUMENT_STATUE_1
#define MSG_TYPE_MONUMENT_WALL_1
struct recipestruct * items
void object_free_drop_inventory(object *ob)
#define MSG_TYPE_PAPER_NOTE_3
#define MSG_TYPE_BOOK_QUARTO_2
archetype * try_find_archetype(const char *name)
event
DIALOGCHECK MINARGS 1 MAXARGS 2
#define MSG_TYPE_CARD_SIMPLE_1
void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2)
#define MSG_TYPE_MONUMENT_STONE_1
static const char *const gods_author[]
struct titleliststruct * next
static const char *const art_author[]
int describe_god(const object *god, int what, StringBuffer *buf, size_t maxlen)
void stringbuffer_delete(StringBuffer *sb)
int book_overflow(const char *buf1, const char *buf2, size_t booksize)
#define MSG_TYPE_PAPER_SCROLL_MAGIC
#define MSG_TYPE_PAPER_SCROLL_NEW_1
static StringBuffer * mon_info_msg(int level, size_t booksize, object *book)
static void new_text_name(object *book, int msgtype)
#define MSG_TYPE_CARD_STRANGE_3
void free_all_readable(void)
sstring get_message_title(const GeneralMessage *message)
static objectlink * first_mon_info
static const char *const art_book_name[]