Atrinik Server  4.0
readable.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
34 #include <global.h>
35 #include <book.h>
36 #include <toolkit/string.h>
37 #include <arch.h>
38 #include <artifact.h>
39 
40 /* This flag is useful for debugging archiving action */
41 /* #define ARCHIVE_DEBUG */
42 
44 typedef struct namebytype {
46  const char *name;
47 
49  int type;
50 } arttypename;
51 
55 static object **monsters = NULL;
59 static size_t num_monsters = 0;
60 
64 static char **msgs = NULL;
68 static size_t num_msgs = 0;
69 
71 static uint32_t spellpathdef[NRSPELLPATHS] = {
72  PATH_PROT,
73  PATH_FIRE,
74  PATH_FROST,
75  PATH_ELEC,
77  PATH_SELF,
82  PATH_MIND,
84  PATH_TELE,
85  PATH_INFO,
90  PATH_DEATH,
92 };
93 
95 static const char *const path_book_name[] = {
96  "codex",
97  "compendium",
98  "exposition",
99  "tables",
100  "treatise",
101  "devotional",
102  "devout notes",
103  "divine text",
104  "divine work",
105  "holy book",
106  "holy record",
107  "moral text",
108  "sacred guide",
109  "testament",
110  "transcript"
111 };
112 
114 static const char *const path_author[] = {
115  "aether",
116  "astral byways",
117  "connections",
118  "the Grey Council",
119  "deep pathways",
120  "knowledge",
121  "magic",
122  "mystic ways",
123  "pathways",
124  "power",
125  "spells",
126  "transforms",
127  "the mystic veil",
128  "unknown spells",
129  "cults",
130  "joy",
131  "lasting curse",
132  "madness",
133  "religions",
134  "the dead",
135  "the gods",
136  "the heirophant",
137  "the poor priest",
138  "the priestess",
139  "pain",
140  "white"
141 };
142 
150  {"Helmet", HELMET},
151  {"Amulet", AMULET},
152  {"Shield", SHIELD},
153  {"Bracers", BRACERS},
154  {"Boots", BOOTS},
155  {"Cloak", CLOAK},
156  {"Gloves", GLOVES},
157  {"Girdle", GIRDLE},
158  {"Ring", RING},
159  {"Missile Weapon", BOW},
160  {"Missile", ARROW},
161  {"Hand Weapon", WEAPON},
162  {"Artifact", SKILL},
163  {"Food", FOOD},
164  {"Body Armour", ARMOUR},
165  {"Pants", PANTS}
166 };
167 
169 static const char *const art_book_name[] = {
170  "collection",
171  "file",
172  "files",
173  "guide",
174  "handbook",
175  "index",
176  "inventory",
177  "list",
178  "listing",
179  "record",
180  "record book"
181 };
182 
184 static const char *const art_author[] = {
185  "ancient things",
186  "artifacts",
187  "Havlor",
188  "items",
189  "lost artifacts",
190  "the ancients",
191  "useful things"
192 };
193 
195 static const char *const mon_book_name[] = {
196  "bestiary",
197  "catalog",
198  "compilation",
199  "collection",
200  "encyclopedia",
201  "guide",
202  "handbook",
203  "list",
204  "manual",
205  "notes",
206  "record",
207  "register",
208  "volume"
209 };
210 
212 static const char *const mon_author[] = {
213  "beasts",
214  "creatures",
215  "dezidens",
216  "dwellers",
217  "evil nature",
218  "life",
219  "monsters",
220  "nature",
221  "new life",
222  "residents",
223  "the spawn",
224  "the living",
225  "things"
226 };
227 
231 static const char *const book_name[] = {
232  "calendar",
233  "datebook",
234  "diary",
235  "guidebook",
236  "handbook",
237  "ledger",
238  "notes",
239  "notebook",
240  "octavo",
241  "pamphlet",
242  "practicum",
243  "script",
244  "transcript",
245  "catalog",
246  "compendium",
247  "guide",
248  "manual",
249  "opus",
250  "tome",
251  "treatise",
252  "volume",
253  "work"
254 };
255 
257 static const char *const book_author[] = {
258  "Abdulah",
259  "Al'hezred",
260  "Alywn",
261  "Arundel",
262  "Arvind",
263  "Aerlingas",
264  "Bacon",
265  "Baliqendii",
266  "Bosworth",
267  "Beathis",
268  "Bertil",
269  "Cauchy",
270  "Chakrabarti",
271  "der Waalis",
272  "Dirk",
273  "Djwimii",
274  "Eisenstaadt",
275  "Fendris",
276  "Frank",
277  "Habbi",
278  "Harlod",
279  "Ichibod",
280  "Janus",
281  "June",
282  "Magnuson",
283  "Nandii",
284  "Nitfeder",
285  "Norris",
286  "Parael",
287  "Penhew",
288  "Sophia",
289  "Skilly",
290  "Tahir",
291  "Thockmorton",
292  "Thomas",
293  "van Helsing",
294  "van Pelt",
295  "Voormis",
296  "Xavier",
297  "Xeno",
298  "Zardoz",
299  "Zagy",
300  "Albertus Magnus",
301 };
302 
315 static int buf_overflow(const char *buf1, const char *buf2, size_t bufsize)
316 {
317  size_t len1 = 0, len2 = 0;
318 
319  if (buf1) {
320  len1 = strlen(buf1);
321  }
322 
323  if (buf2) {
324  len2 = strlen(buf2);
325  }
326 
327  if ((len1 + len2) >= bufsize) {
328  return 1;
329  }
330 
331  return 0;
332 }
333 
346 int book_overflow(const char *buf1, const char *buf2, size_t booksize)
347 {
348  /* 2 less so always room for trailing \n */
349  if (buf_overflow(buf1, buf2, BOOK_BUF - 2) || buf_overflow(buf1, buf2, booksize)) {
350  return 1;
351  }
352 
353  return 0;
354 }
355 
359 static void init_msgfile(void)
360 {
361  FILE *fp;
362  char buf[MAX_BUF], fname[MAX_BUF], *cp;
363 
364  msgs = NULL;
365  num_msgs = 0;
366 
367  snprintf(fname, sizeof(fname), "%s/messages", settings.libpath);
368 
369  fp = fopen(fname, "r");
370 
371  if (fp) {
372  int lineno, error_lineno = 0, in_msg = 0;
373  char msgbuf[HUGE_BUF];
374 
375  for (lineno = 1; fgets(buf, sizeof(buf), fp); lineno++) {
376  if (*buf == '#' || (*buf == '\n' && !in_msg)) {
377  continue;
378  }
379 
380  cp = strchr(buf, '\n');
381 
382  if (cp) {
383  while (cp > buf && (cp[-1] == ' ' || cp[-1] == '\t')) {
384  cp--;
385  }
386 
387  *cp = '\0';
388  }
389 
390  if (in_msg) {
391  if (!strcmp(buf, "ENDMSG")) {
392  if (strlen(msgbuf) > BOOK_BUF) {
393  LOG(BUG, "This string exceeded max book buf size: %s", msgbuf);
394  }
395 
396  num_msgs++;
397  msgs = erealloc(msgs, sizeof(char *) * num_msgs);
398  msgs[num_msgs - 1] = estrdup(msgbuf);
399  in_msg = 0;
400  } else if (!buf_overflow(msgbuf, buf, sizeof(msgbuf) - 1)) {
401  strcat(msgbuf, buf);
402  strcat(msgbuf, "\n");
403  } else if (error_lineno != 0) {
404  LOG(BUG, "Truncating book at %s, line %d", fname, error_lineno);
405  error_lineno = 0;
406  }
407  } else if (!strcmp(buf, "MSG")) {
408  error_lineno = lineno;
409  msgbuf[0] = '\0';
410  in_msg = 1;
411  } else {
412  LOG(BUG, "Syntax error at %s, line %d", fname, lineno);
413  }
414  }
415 
416  fclose(fp);
417  }
418 }
419 
423 static void init_mon_info(void)
424 {
425  monsters = NULL;
426  num_monsters = 0;
427 
428  archetype_t *at, *tmp;
429  HASH_ITER(hh, arch_table, at, tmp) {
430  if (!QUERY_FLAG(&at->clone, FLAG_MONSTER)) {
431  continue;
432  }
433 
434  monsters = erealloc(monsters, sizeof(*monsters) * (num_monsters + 1));
435  monsters[num_monsters] = &at->clone;
436  num_monsters++;
437  }
438 }
439 
447 void init_readable(void)
448 {
449  init_msgfile();
450  init_mon_info();
451 }
452 
465 static void new_text_name(object *book, int msgtype)
466 {
467  const char *name;
468 
469  if (book->type != BOOK) {
470  return;
471  }
472 
473  switch (msgtype) {
474  case MSGTYPE_MONSTER:
475  name = mon_book_name[rndm(1, arraysize(mon_book_name)) - 1];
476  break;
477 
478  case MSGTYPE_ARTIFACT:
479  name = art_book_name[rndm(1, arraysize(art_book_name)) - 1];
480  break;
481 
482  case MSGTYPE_SPELLPATH:
483  name = path_book_name[rndm(1, arraysize(path_book_name)) - 1];
484  break;
485 
486  case MSGTYPE_MSGFILE:
487  default:
488  name = book_name[rndm(1, arraysize(book_name)) - 1];
489  break;
490  }
491 
492  FREE_AND_COPY_HASH(book->name, name);
493 }
494 
503 static void add_author(object *op, int msgtype)
504 {
505  char title[MAX_BUF];
506  const char *name;
507 
508  if (msgtype < 0 || strlen(op->msg) < 5) {
509  return;
510  }
511 
512  switch (msgtype) {
513  case MSGTYPE_MONSTER:
514  name = mon_author[rndm(1, arraysize(mon_author)) - 1];
515  break;
516 
517  case MSGTYPE_ARTIFACT:
518  name = art_author[rndm(1, arraysize(art_author)) - 1];
519  break;
520 
521  case MSGTYPE_SPELLPATH:
522  name = path_author[rndm(1, arraysize(path_author)) - 1];
523  break;
524 
525  case MSGTYPE_MSGFILE:
526  default:
527  name = book_author[rndm(1, arraysize(book_author)) - 1];
528  }
529 
530  snprintf(title, sizeof(title), "of %s", name);
531  FREE_AND_COPY_HASH(op->title, title);
532 }
533 
546 static void change_book(object *book, int msgtype)
547 {
548  if (book->type != BOOK || book->title) {
549  return;
550  }
551 
552  /* Random book name */
553  new_text_name(book, msgtype);
554  /* Random author */
555  add_author(book, msgtype);
556 }
557 
563 object *get_random_mon(void)
564 {
565  /* Safety. */
566  if (!monsters || !num_monsters) {
567  return NULL;
568  }
569 
570  return monsters[rndm(1, num_monsters) - 1];
571 }
572 
584 static char *mon_desc(object *mon, char *buf, size_t size)
585 {
586  char *desc = object_get_description_s(mon, NULL);
587  snprintf(buf, size, "[title]%s[/title]\n%s", mon->name, desc);
588  efree(desc);
589  return buf;
590 }
591 
602 static char *mon_info_msg(char *buf, size_t booksize)
603 {
604  char tmpbuf[HUGE_BUF], desc[MAX_BUF];
605  object *tmp;
606 
607  /* Preamble */
608  strncpy(buf, "[title]Bestiary[/title]\nHerein are detailed creatures found in the world around.\n", booksize - 1);
609 
610  /* Lets print info on as many monsters as will fit in our
611  * document. */
612  while ((tmp = get_random_mon())) {
613  snprintf(tmpbuf, sizeof(tmpbuf), "\n%s", mon_desc(tmp, desc, sizeof(desc)));
614 
615  if (!rndm(0, 6) || book_overflow(buf, tmpbuf, booksize)) {
616  break;
617  }
618 
619  snprintf(buf + strlen(buf), booksize - strlen(buf), "%s", tmpbuf);
620  }
621 
622  return buf;
623 }
624 
637 static char *artifact_msg(int level, char *buf, size_t booksize)
638 {
639  artifact_list_t *al;
640  artifact_t *art;
641  int chance, i, type, idx;
642  int book_entries = level > 5 ? RANDOM () % 3 + RANDOM () % 3 + 2 : RANDOM () % level + 1;
643  char *final;
644  object *tmp = NULL;
645  StringBuffer *desc;
646 
647  /* Values greater than 5 create msg buffers that are too big! */
648  if (book_entries > 5) {
649  book_entries = 5;
650  }
651 
652  /* Let's determine what kind of artifact type randomly.
653  * Right now legal artifacts only come from those listed
654  * in art_name_array. Also, we check to be sure an artifactlist
655  * for that type exists! */
656  i = 0;
657 
658  do {
659  idx = rndm(1, arraysize(art_name_array)) - 1;
660  type = art_name_array[idx].type;
661  al = artifact_list_find(type);
662  i++;
663  } while (al == NULL && i < 10);
664 
665  /* Unable to find a message */
666  if (i == 10) {
667  snprintf(buf, booksize, "None");
668  return buf;
669  }
670 
671  /* There is no reason to start on the artifact list at the beginning. Lets
672  * take our starting position randomly... */
673  art = al->items;
674 
675  for (i = rndm(1, level) + rndm(0, 1); i > 0; i--) {
676  /* Out of stuff, loop back around */
677  if (art == NULL) {
678  art = al->items;
679  }
680 
681  art = art->next;
682  }
683 
684  /* Ok, let's print out the contents */
685  snprintf(buf, booksize, "[title]Magical %s[/title]\nHerein %s detailed %s...\n", art_name_array[idx].name, book_entries > 1 ? "are" : "is", book_entries > 1 ? "some artifacts" : "an artifact");
686 
687  /* Artifact msg attributes loop. Let's keep adding entries to the 'book'
688  * as long as we have space up to the allowed max # (book_entries) */
689  while (book_entries > 0) {
690  if (art == NULL) {
691  art = al->items;
692  }
693 
694  desc = stringbuffer_new();
695  tmp = arch_to_object(art->def_at);
697 
698  stringbuffer_append_string(desc, "\n[title]");
699  desc = object_get_material_name(tmp, NULL, desc);
700  stringbuffer_append_string(desc, "[/title]\nIt is ");
701 
702  /* Chance of finding. */
703  chance = 100 * ((float) art->chance / al->total_chance);
704 
705  if (chance >= 20) {
706  stringbuffer_append_string(desc, "an uncommon");
707  } else if (chance >= 10) {
708  stringbuffer_append_string(desc, "an unusual");
709  } else if (chance >= 5) {
710  stringbuffer_append_string(desc, "a rare");
711  } else {
712  stringbuffer_append_string(desc, "a very rare");
713  }
714 
715  /* Value of artifact. */
716  stringbuffer_append_printf(desc, " item with a value of %s.", shop_get_cost_string(tmp->value));
717 
718  StringBuffer *sb = object_get_description(tmp, NULL, NULL);
719  if (stringbuffer_length(sb) > 1) {
720  stringbuffer_append_string(desc,
721  "\nProperties of this artifact include:\n");
722  stringbuffer_append_stringbuffer(desc, sb);
723  }
724  stringbuffer_free(sb);
725 
726  object_destroy(tmp);
727  final = stringbuffer_finish(desc);
728 
729  /* Add the buf if it will fit. */
730  if (book_overflow(buf, final, booksize)) {
731  efree(final);
732  break;
733  }
734 
735  snprintf(buf + strlen(buf), booksize - strlen(buf), "%s", final);
736  efree(final);
737 
738  art = art->next;
739  book_entries--;
740  }
741 
742  return buf;
743 }
744 
757 static char *spellpath_msg(int level, char *buf, size_t booksize)
758 {
759  int path = rndm(1, NRSPELLPATHS) - 1;
760  int i, did_first_sp = 0;
761  uint32_t pnum = spellpathdef[path];
762  StringBuffer *desc;
763  char *final;
764 
765  desc = stringbuffer_new();
766  buf[0] = '\0';
767 
768  /* Preamble */
769  stringbuffer_append_printf(desc, "[title]Path of %s[/title]\nHerein are detailed the names of incantations belonging to the path of %s:\n\n", spellpathnames[path], spellpathnames[path]);
770 
771  /* Now go through the entire list of spells. Add appropriate spells
772  * in our message buffer */
773  for (i = 0; i < NROFREALSPELLS; i++) {
774  if (!(pnum & spells[i].path)) {
775  continue;
776  }
777 
778  if (strlen(spells[i].name) + stringbuffer_length(desc) >= booksize) {
779  break;
780  }
781 
782  if (did_first_sp) {
783  stringbuffer_append_string(desc, ",\n");
784  }
785 
786  did_first_sp = 1;
787  stringbuffer_append_string(desc, spells[i].name);
788  }
789 
790  final = stringbuffer_finish(desc);
791 
792  /* Geez, no spells were generated. */
793  if (!did_first_sp) {
794  snprintf(buf + strlen(buf), booksize - strlen(buf), "%s\n - no known spells exist -\n", final);
795  } else {
796  snprintf(buf + strlen(buf), booksize - strlen(buf), "%s\n", final);
797  }
798 
799  efree(final);
800  return buf;
801 }
802 
810 static char *msgfile_msg(size_t booksize)
811 {
812  static char buf[BOOK_BUF];
813  char *msg = NULL;
814 
815  /* Get a random message. */
816  if (msgs && num_msgs) {
817  msg = msgs[rndm(1, num_msgs) - 1];
818  }
819 
820  if (msg && !book_overflow(buf, msg, booksize)) {
821  strncpy(buf, msg, sizeof(buf) - 1);
822  } else {
823  strncpy(buf, "*undecipherable text*", sizeof(buf) - 1);
824  }
825 
826  return buf;
827 }
828 
847 void tailor_readable_ob(object *book, int msg_type)
848 {
849  char msgbuf[BOOK_BUF];
850  int level = book->level ? (RANDOM () % book->level) + 1 : 1;
851 
852  /* Safety. */
853  if (book->type != BOOK) {
854  return;
855  }
856 
857  /* If no level no point in doing any more... */
858  if (level <= 0) {
859  return;
860  }
861 
862  msg_type = msg_type > 0 ? msg_type : rndm(0, MSGTYPE_NUM);
863 
864  switch (msg_type) {
865  case MSGTYPE_MONSTER:
866  mon_info_msg(msgbuf, BOOK_BUF);
867  break;
868 
869  case MSGTYPE_ARTIFACT:
870  artifact_msg(level, msgbuf, BOOK_BUF);
871  break;
872 
873  case MSGTYPE_SPELLPATH:
874  spellpath_msg(level, msgbuf, BOOK_BUF);
875  break;
876 
877  case MSGTYPE_MSGFILE:
878  default:
879  snprintf(VS(msgbuf), "%s", msgfile_msg(BOOK_BUF));
880  break;
881  }
882 
883  /* Safety -- we get ugly map saves/crashes without this */
884  snprintfcat(VS(msgbuf), "\n");
885 
886  if (strlen(msgbuf) > 1) {
887  FREE_AND_COPY_HASH(book->msg, msgbuf);
888  /* Let's give the "book" a new name, which may be a compound word */
889  change_book(book, msg_type);
890  }
891 }
892 
897 {
898  size_t i;
899 
900  for (i = 0; i < num_msgs; i++) {
901  efree(msgs[i]);
902  }
903 
904  efree(msgs);
905  efree(monsters);
906 }
static char * spellpath_msg(int level, char *buf, size_t booksize)
Definition: readable.c:757
#define FREE_AND_COPY_HASH(_sv_, _nv_)
Definition: global.h:100
#define PATH_TURNING
Definition: spells.h:70
archetype_t * arch_table
Definition: arch.c:41
void object_destroy(object *ob)
Definition: object.c:1441
const char * shop_get_cost_string(int64_t cost)
Definition: shop.c:178
struct artifact * items
Artifacts in this artifact list.
Definition: artifact.h:84
static void init_msgfile(void)
Definition: readable.c:359
#define BOOK
Definition: define.h:150
#define NRSPELLPATHS
Definition: define.h:666
#define PATH_CREATE
Definition: spells.h:60
uint8_t type
One of operation types.
Definition: sound_ambient.c:45
static size_t num_monsters
Definition: readable.c:59
static object ** monsters
Definition: readable.c:55
#define NROFREALSPELLS
Definition: define.h:664
object * get_random_mon(void)
Definition: readable.c:563
#define GIRDLE
Definition: define.h:461
#define BOW
Definition: define.h:174
static const char *const path_book_name[]
Definition: readable.c:95
#define PATH_SELF
Definition: spells.h:48
#define SHIELD
Definition: define.h:214
#define BRACERS
Definition: define.h:433
static int buf_overflow(const char *buf1, const char *buf2, size_t bufsize)
Definition: readable.c:315
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
const char *const spellpathnames[NRSPELLPATHS]
Definition: spellist.h:349
char libpath[MAX_BUF]
Definition: global.h:338
#define PATH_SUMMON
Definition: spells.h:50
#define PATH_TRANSMUTE
Definition: spells.h:66
#define ARMOUR
Definition: define.h:182
static char * msgfile_msg(size_t booksize)
Definition: readable.c:810
const char * title
Definition: object.h:171
static const char *const mon_book_name[]
Definition: readable.c:195
const char * name
Definition: readable.c:46
static char ** msgs
Definition: readable.c:64
Definition: arch.h:40
StringBuffer * object_get_material_name(const object *op, const object *caller, StringBuffer *sb)
Definition: item.c:471
#define PATH_RESTORE
Definition: spells.h:54
#define PATH_FIRE
Definition: spells.h:40
artifact_list_t * artifact_list_find(uint8_t type)
Definition: artifact.c:397
#define PATH_WOUNDING
Definition: spells.h:72
struct namebytype arttypename
#define BOOK_BUF
Definition: book.h:38
#define PATH_MISSILE
Definition: spells.h:46
#define PATH_INFO
Definition: spells.h:64
static arttypename art_name_array[]
Definition: readable.c:149
const char * name
Definition: object.h:168
#define SET_FLAG(xyz, p)
Definition: define.h:741
object * arch_to_object(archetype_t *at)
Definition: arch.c:446
void tailor_readable_ob(object *book, int msg_type)
Definition: readable.c:847
#define PATH_PROT
Definition: spells.h:38
static char * mon_info_msg(char *buf, size_t booksize)
Definition: readable.c:602
static const char *const book_author[]
Definition: readable.c:257
#define ARROW
Definition: define.h:170
void init_readable(void)
Definition: readable.c:447
static void add_author(object *op, int msgtype)
Definition: readable.c:503
static const char *const mon_author[]
Definition: readable.c:212
static uint32_t spellpathdef[NRSPELLPATHS]
Definition: readable.c:71
spell_struct spells[NROFREALSPELLS]
Definition: spellist.h:34
#define PATH_DETONATE
Definition: spells.h:56
struct settings_struct settings
Definition: init.c:55
static const char *const book_name[]
Definition: readable.c:231
#define RING
Definition: define.h:320
#define PATH_LIGHT
Definition: spells.h:76
static const char *const art_author[]
Definition: readable.c:184
static char * mon_desc(object *mon, char *buf, size_t size)
Definition: readable.c:584
static char * artifact_msg(int level, char *buf, size_t booksize)
Definition: readable.c:637
int type
Definition: readable.c:49
#define SKILL
Definition: define.h:246
uint8_t type
Definition: object.h:360
#define WEAPON
Definition: define.h:178
int book_overflow(const char *buf1, const char *buf2, size_t booksize)
Definition: readable.c:346
void free_all_readable(void)
Definition: readable.c:896
#define FOOD
Definition: define.h:142
static const char *const path_author[]
Definition: readable.c:114
const char * msg
Definition: object.h:183
#define FLAG_MONSTER
Definition: define.h:922
#define HELMET
Definition: define.h:218
static void change_book(object *book, int msgtype)
Definition: readable.c:546
static void init_mon_info(void)
Definition: readable.c:423
#define BOOTS
Definition: define.h:413
#define PATH_FROST
Definition: spells.h:42
char * object_get_description_s(const object *op, const object *caller)
Definition: item.c:1222
#define GLOVES
Definition: define.h:417
#define PATH_DEATH
Definition: spells.h:74
StringBuffer * object_get_description(const object *op, const object *caller, StringBuffer *sb)
Definition: item.c:839
#define PATH_TELE
Definition: spells.h:62
#define PATH_ELEC
Definition: spells.h:44
#define PANTS
Definition: define.h:222
#define PATH_ABJURE
Definition: spells.h:52
#define AMULET
Definition: define.h:234
#define CLOAK
Definition: define.h:381
struct archetype * def_at
Definition: artifact.h:51
static void new_text_name(object *book, int msgtype)
Definition: readable.c:465
static const char *const art_book_name[]
Definition: readable.c:169
int8_t level
Definition: object.h:347
int64_t value
Definition: object.h:240
uint16_t total_chance
Sum of chance for all artifacts on this list.
Definition: artifact.h:85
object clone
An object from which to do object_copy().
Definition: arch.h:47
#define PATH_MIND
Definition: spells.h:58
#define PATH_TRANSFER
Definition: spells.h:68
struct artifact * next
Next artifact in the list.
Definition: artifact.h:40
static size_t num_msgs
Definition: readable.c:68
#define FLAG_IDENTIFIED
Definition: define.h:980
uint16_t chance
Chance.
Definition: artifact.h:63