Crossfire Server, Trunk  R22010
artifact.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 #include "global.h"
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25 
26 #include "loader.h"
27 
40  artifactlist *tl = (artifactlist *)malloc(sizeof(artifactlist));
41  if (tl == NULL)
43  tl->next = NULL;
44  tl->items = NULL;
45  tl->total_chance = 0;
46  return tl;
47 }
48 
59  artifact *t = (artifact *)malloc(sizeof(artifact));
60  if (t == NULL)
62  t->item = NULL;
63  t->next = NULL;
64  t->chance = 0;
65  t->difficulty = 0;
66  t->allowed = NULL;
67  t->allowed_size = 0;
68  return t;
69 }
70 
77 static void free_charlinks(linked_char *lc) {
78  if (lc->next)
79  free_charlinks(lc->next);
80  free(lc);
81 }
82 
95 static void free_artifact(artifact *at) {
96  object *next;
97 
98  if (at->next)
99  free_artifact(at->next);
100  if (at->allowed)
101  free_charlinks(at->allowed);
102  while (at->item) {
103  next = at->item->next;
104  if (at->item->name)
105  free_string(at->item->name);
106  if (at->item->name_pl)
107  free_string(at->item->name_pl);
108  if (at->item->msg)
109  free_string(at->item->msg);
110  if (at->item->title)
111  free_string(at->item->title);
113  free(at->item);
114  at->item = next;
115  }
116  free(at);
117 }
118 
125 static void free_artifactlist(artifactlist *al) {
126  artifactlist *nextal;
127 
128  for (; al != NULL; al = nextal) {
129  nextal = al->next;
130  if (al->items) {
131  free_artifact(al->items);
132  }
133  free(al);
134  }
135 }
136 
140 void free_all_artifacts(void) {
142  first_artifactlist = NULL;
143 }
144 
146 #define ARTIFACT_TRIES 2
147 
155 void generate_artifact(object *op, int difficulty) {
156  const artifactlist *al;
157  const artifact *art;
158  int i;
159 
160  al = find_artifactlist(op->type);
161 
162  if (al == NULL) {
163  return;
164  }
165 
166  for (i = 0; i < ARTIFACT_TRIES; i++) {
167  int roll = RANDOM()%al->total_chance;
168 
169  for (art = al->items; art != NULL; art = art->next) {
170  roll -= art->chance;
171  if (roll < 0)
172  break;
173  }
174 
175  if (art == NULL || roll >= 0) {
176  LOG(llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", op->type);
177  return;
178  }
179  if (!strcmp(art->item->name, "NONE"))
180  return;
181  if (FABS(op->magic) < art->item->magic)
182  continue; /* Not magic enough to be this item */
183 
184  /* Map difficulty not high enough */
185  if (difficulty < art->difficulty)
186  continue;
187 
188  if (!legal_artifact_combination(op, art)) {
189 #ifdef TREASURE_VERBOSE
190  LOG(llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name);
191 #endif
192  continue;
193  }
194  give_artifact_abilities(op, art->item);
195  return;
196  }
197 }
198 
203 void give_artifact_abilities(object *op, const object *artifact) {
204  char new_name[MAX_BUF];
205 
206  snprintf(new_name, sizeof(new_name), "of %s", artifact->name);
207  if (op->title)
208  free_string(op->title);
209  op->title = add_string(new_name);
210  if (op->artifact)
211  free_string(op->artifact);
212  op->artifact = add_refcount(artifact->name);
213  add_abilities(op, artifact); /* Give out the bonuses */
214 
215  return;
216 }
217 
221 int legal_artifact_combination(const object *op, const artifact *art) {
222  int neg, success = 0;
223  linked_char *tmp;
224  const char *name;
225 
226  if (art->allowed == (linked_char *)NULL)
227  return 1; /* Ie, "all" */
228  for (tmp = art->allowed; tmp; tmp = tmp->next) {
229 #ifdef TREASURE_VERBOSE
230  LOG(llevDebug, "legal_art: %s\n", tmp->name);
231 #endif
232  if (*tmp->name == '!') {
233  name = tmp->name+1;
234  neg = 1;
235  } else {
236  name = tmp->name;
237  neg = 0;
238  }
239 
240  /* If we match name, then return the opposite of 'neg' */
241  if (!strcmp(name, op->name) || (op->arch && !strcmp(name, op->arch->name)))
242  return !neg;
243 
244  /* Set success as true, since if the match was an inverse, it means
245  * everything is allowed except what we match
246  */
247  else if (neg)
248  success = 1;
249  }
250  return success;
251 }
252 
260 static void compute_face_name(char* buf, size_t size, const char* name, const char* suffix)
261 {
262  const char* dot = name + strlen(name) - 1;
263  while (dot > name && (isdigit(*dot) || (*dot == 'x')))
264  {
265  dot--;
266  }
267 
268  if (*dot == '.')
269  {
270  buf[0] = '0';
271  strlcpy(buf, name, dot - name + 1);
272  snprintf(buf + strlen(buf), size - strlen(buf), "_%s%s", suffix, dot);
273  }
274  else
275  {
276  snprintf(buf, size, "%s_%s", name, suffix);
277  }
278 }
279 
280 /* Keys used for artifact stuff, not copied */
281 #define KEY_FACE_SUFFIX "face_suffix"
282 #define KEY_ANIMATION_SUFFIX "animation_suffix"
283 
288 void add_abilities(object *op, const object *change) {
289  int i, tmp;
290  char buf[MAX_BUF];
291  sstring key;
292 
293  if (change->face != NULL && change->face != blank_face) {
294 #ifdef TREASURE_VERBOSE
295  LOG(llevDebug, "FACE: %d\n", change->face->number);
296 #endif
297 
298  object_set_value(op, "identified_face", change->face->name, 1);
299  } else if ((key = object_get_value(change, KEY_FACE_SUFFIX)) != NULL) {
300  const Face* face;
301  compute_face_name(buf, sizeof(buf), op->face->name, key);
302  face = try_find_face(buf, op->face);
303  object_set_value(op, "identified_face", face->name, 1);
304  }
305  if (QUERY_FLAG(change, FLAG_CLIENT_ANIM_RANDOM)) {
306  object_set_value(op, "identified_anim_random", "1", 1);
307  }
308  if (change->anim_speed > 0) {
309  snprintf(buf, sizeof(buf), "%d", change->anim_speed);
310  object_set_value(op, "identified_anim_speed", buf, 1);
311  }
312  if (change->animation != NULL && op->arch != NULL) {
313  /* op->arch can be NULL when called from artifact_msg(). */
314  object_set_value(op, "identified_animation", change->animation->name, 1);
315  } else if (op->animation != NULL && (key = object_get_value(change, KEY_ANIMATION_SUFFIX)) != NULL) {
316  const Animations *anim;
317  snprintf(buf, sizeof(buf), "%s_%s", op->animation->name, key);
318  anim = try_find_animation(buf);
319  if (anim != NULL) {
320  object_set_value(op, "identified_animation", anim->name, 1);
321  }
322  }
323 
336  if (op->arch && (is_identified(op) || QUERY_FLAG(change, FLAG_IDENTIFIED)))
338 
339  for (i = 0; i < NUM_STATS; i++)
340  change_attr_value(&(op->stats), i, get_attr_value(&(change->stats), i));
341 
342  op->attacktype |= change->attacktype;
343  op->path_attuned |= change->path_attuned;
344  op->path_repelled |= change->path_repelled;
345  op->path_denied |= change->path_denied;
346  op->move_type |= change->move_type;
347  op->stats.luck += change->stats.luck;
348 
349  if (QUERY_FLAG(change, FLAG_CURSED))
350  SET_FLAG(op, FLAG_CURSED);
351  if (QUERY_FLAG(change, FLAG_DAMNED))
352  SET_FLAG(op, FLAG_DAMNED);
353  if ((QUERY_FLAG(change, FLAG_CURSED) || QUERY_FLAG(change, FLAG_DAMNED))
354  && op->magic > 0)
355  set_abs_magic(op, -op->magic);
356 
357  if (QUERY_FLAG(change, FLAG_LIFESAVE))
358  SET_FLAG(op, FLAG_LIFESAVE);
359  if (QUERY_FLAG(change, FLAG_REFL_SPELL))
361  if (QUERY_FLAG(change, FLAG_STEALTH))
362  SET_FLAG(op, FLAG_STEALTH);
363  if (QUERY_FLAG(change, FLAG_XRAYS))
364  SET_FLAG(op, FLAG_XRAYS);
365  if (QUERY_FLAG(change, FLAG_BLIND))
366  SET_FLAG(op, FLAG_BLIND);
367  if (QUERY_FLAG(change, FLAG_CONFUSED))
368  SET_FLAG(op, FLAG_CONFUSED);
369  if (QUERY_FLAG(change, FLAG_SEE_IN_DARK))
371  if (QUERY_FLAG(change, FLAG_REFL_MISSILE))
373  if (QUERY_FLAG(change, FLAG_MAKE_INVIS))
375 
376  if (QUERY_FLAG(change, FLAG_STAND_STILL)) {
378  /* so artifacts will join */
379  if (!QUERY_FLAG(op, FLAG_ALIVE))
380  op->speed = 0.0;
382  }
383  if (change->nrof)
384  op->nrof = RANDOM()%((int)change->nrof)+1;
385  op->stats.exp += change->stats.exp; /* Speed modifier */
386  op->stats.wc += change->stats.wc;
387  op->stats.ac += change->stats.ac;
388 
389  if (change->other_arch) {
390  /* Basically, for horns & potions, the other_arch field is the spell
391  * to cast. So convert that to into a spell and put it into
392  * this object.
393  */
394  if (op->type == ROD || op->type == POTION) {
395  object *tmp_obj;
396 
397  /* Remove any spells this object currently has in it */
398  while (op->inv) {
399  tmp_obj = op->inv;
400  object_remove(tmp_obj);
402  }
403  tmp_obj = arch_to_object(change->other_arch);
404  /* This is an artifact, so this function will be called at load time,
405  * thus we don't need to keep the inventory */
406  SET_FLAG(tmp_obj, FLAG_NO_SAVE);
407  object_insert_in_ob(tmp_obj, op);
408  }
409  /* No harm setting this for potions/horns */
410  op->other_arch = change->other_arch;
411  }
412 
413  if (change->stats.hp < 0)
414  op->stats.hp = -change->stats.hp;
415  else
416  op->stats.hp += change->stats.hp;
417  if (change->stats.maxhp < 0)
418  op->stats.maxhp = -change->stats.maxhp;
419  else
420  op->stats.maxhp += change->stats.maxhp;
421  if (change->stats.sp < 0)
422  op->stats.sp = -change->stats.sp;
423  else
424  op->stats.sp += change->stats.sp;
425  if (change->stats.maxsp < 0)
426  op->stats.maxsp = -change->stats.maxsp;
427  else
428  op->stats.maxsp += change->stats.maxsp;
429  if (change->stats.food < 0)
430  op->stats.food = -(change->stats.food);
431  else
432  op->stats.food += change->stats.food;
433  if (change->level < 0)
434  op->level = -(change->level);
435  else
436  op->level += change->level;
437 
438  op->item_power = change->item_power;
439 
440  for (i = 0; i < NROFATTACKS; i++) {
441  if (change->resist[i]) {
442  op->resist[i] += change->resist[i];
443  }
444  }
445  if (change->stats.dam) {
446  if (change->stats.dam < 0)
447  op->stats.dam = (-change->stats.dam);
448  else if (op->stats.dam) {
449  tmp = (int)(((int)op->stats.dam*(int)change->stats.dam)/10);
450  if (tmp == op->stats.dam) {
451  if (change->stats.dam < 10)
452  op->stats.dam--;
453  else
454  op->stats.dam++;
455  } else
456  op->stats.dam = tmp;
457  }
458  }
459  if (change->weight) {
460  if (change->weight < 0)
461  op->weight = (-change->weight);
462  else
463  op->weight = (op->weight*(change->weight))/100;
464  }
465  if (change->last_sp) {
466  if (change->last_sp < 0)
467  op->last_sp = (-change->last_sp);
468  else
469  op->last_sp = (signed char)(((int)op->last_sp*(int)change->last_sp)/(int)100);
470  }
471  if (change->gen_sp_armour) {
472  if (change->gen_sp_armour < 0)
473  op->gen_sp_armour = (-change->gen_sp_armour);
474  else
475  op->gen_sp_armour = (signed char)(((int)op->gen_sp_armour*((int)change->gen_sp_armour))/(int)100);
476  }
477  op->value *= change->value;
478 
479  if (change->material)
480  op->material = change->material;
481 
482  if (change->materialname) {
483  if (op->materialname)
484  free_string(op->materialname);
485  op->materialname = add_refcount(change->materialname);
486  }
487 
488  if (change->slaying) {
489  if (op->slaying)
490  free_string(op->slaying);
491  op->slaying = add_refcount(change->slaying);
492  }
493  if (change->race) {
494  if (op->race)
495  free_string(op->race);
496  op->race = add_refcount(change->race);
497  }
498  if (change->msg)
499  object_set_msg(op, change->msg);
500 
501  if (change->key_values) {
502  const key_value *kv = change->key_values;
503  while (kv) {
504  if (strcmp(kv->key, KEY_FACE_SUFFIX) != 0 && strcmp(kv->key, KEY_ANIMATION_SUFFIX) != 0) {
505  object_set_value(op, kv->key, kv->value, 1);
506  }
507  kv = kv->next;
508  }
509  }
510 
511  if (change->inv) {
512  object *copy;
513 
514  FOR_INV_PREPARE(change, inv) {
515  copy = object_new();
516  object_copy(inv, copy);
517  object_insert_in_ob(copy, op);
518  } FOR_INV_FINISH();
519  }
520 }
521 
531  artifactlist *al;
532 
533  for (al = first_artifactlist; al != NULL; al = al->next)
534  if (al->type == type)
535  return al;
536  return NULL;
537 }
538 
543 void init_artifacts(FILE *file, const char *filename) {
544  char buf[HUGE_BUF], *cp, *next;
545  artifact *art = NULL;
546  linked_char *tmp;
547  int value;
548  artifactlist *al;
549  archetype dummy_archetype;
550 
551  memset(&dummy_archetype, 0, sizeof(archetype));
552 
553  artifact_init = 1;
554 
555  while (fgets(buf, HUGE_BUF, file) != NULL) {
556  if (*buf == '#')
557  continue;
558  if ((cp = strchr(buf, '\n')) != NULL)
559  *cp = '\0';
560  cp = buf;
561  while (*cp == ' ') /* Skip blanks */
562  cp++;
563  if (*cp == '\0')
564  continue;
565 
566  if (!strncmp(cp, "Allowed", 7)) {
567  if (art == NULL) {
568  art = get_empty_artifact();
569  nrofartifacts++;
570  }
571 
572  cp = strchr(cp, ' ')+1;
573  while (*(cp+strlen(cp)-1) == ' ')
574  cp[strlen(cp)-1] = '\0';
575 
576  if (!strcmp(cp, "all"))
577  continue;
578 
579  do {
580  while (*cp == ' ')
581  cp++;
582  nrofallowedstr++;
583  if ((next = strchr(cp, ',')) != NULL)
584  *(next++) = '\0';
585  tmp = (linked_char *)malloc(sizeof(linked_char));
586  tmp->name = add_string(cp);
587  tmp->next = art->allowed;
588  art->allowed = tmp;
589  art->allowed_size++;
590  } while ((cp = next) != NULL);
591  } else if (sscanf(cp, "chance %d", &value))
592  art->chance = (uint16_t)value;
593  else if (sscanf(cp, "difficulty %d", &value))
594  art->difficulty = (uint8_t)value;
595  else if (!strncmp(cp, "Object", 6)) {
596  art->item = (object *)calloc(1, sizeof(object));
597  if (art->item == NULL) {
598  LOG(llevError, "init_artifacts: memory allocation failure.\n");
599  abort();
600  }
601  object_reset(art->item);
602  art->item->arch = &dummy_archetype;
603  if (!load_object(file, art->item, LO_LINEMODE, MAP_STYLE))
604  LOG(llevError, "Init_Artifacts: Could not load object.\n");
605  art->item->arch = NULL;
606  art->item->name = add_string((strchr(cp, ' ')+1));
607  al = find_artifactlist_internal(art->item->type);
608  if (al == NULL) {
609  al = get_empty_artifactlist();
610  al->type = art->item->type;
611  al->next = first_artifactlist;
612  first_artifactlist = al;
613  }
614  art->next = al->items;
615  al->items = art;
616  art = NULL;
617  } else
618  LOG(llevError, "Unknown input in artifact file %s: %s\n", filename, buf);
619  }
620 
621  for (al = first_artifactlist; al != NULL; al = al->next) {
622  al->total_chance = 0;
623  for (art = al->items; art != NULL; art = art->next) {
624  if (!art->chance)
625  LOG(llevDebug, "Artifact with no chance: %s\n", art->item->name);
626  else
627  al->total_chance += art->chance;
628  }
629 #if 0
630  LOG(llevDebug, "Artifact list type %d has %d total chance\n", al->type, al->total_chance);
631 #endif
632  }
633 
634  artifact_init = 0;
635 }
636 
644 const artifactlist *find_artifactlist(int type) {
645  return find_artifactlist_internal(type);
646 }
647 
654 const artifact *find_artifact(const object *op, const char *name) {
655  artifactlist *list;
656  artifact *at;
657  sstring sname = find_string(name);
658 
659  if (sname == NULL)
660  return NULL;
661 
662  list = find_artifactlist_internal(op->type);
663  if (list == NULL)
664  return NULL;
665 
666  for (at = list->items; at != NULL; at = at->next) {
667  if (at->item->name == sname && legal_artifact_combination(op, at))
668  return at;
669  }
670 
671  return NULL;
672 }
673 
680 void dump_artifacts(void) {
681  artifactlist *al;
682  artifact *art;
683  linked_char *next;
684 
685  fprintf(logfile, "\n");
686  for (al = first_artifactlist; al != NULL; al = al->next) {
687  fprintf(logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance);
688  for (art = al->items; art != NULL; art = art->next) {
689  fprintf(logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", art->item->name, art->difficulty, art->chance);
690  if (art->allowed != NULL) {
691  fprintf(logfile, "\tAllowed combinations:");
692  for (next = art->allowed; next != NULL; next = next->next)
693  fprintf(logfile, "%s,", next->name);
694  fprintf(logfile, "\n");
695  }
696  }
697  }
698  fprintf(logfile, "\n");
699 }
700 
706 unsigned artifact_get_face(const artifact *art) {
707  archetype *arch = get_next_archetype(NULL);
708 
709  if (art->item->face != blank_face && art->item->face != NULL)
710  return art->item->face->number;
711 
712  if (art->allowed_size > 0) {
713  if (art->allowed->name[0] == '!') {
714  linked_char *allowed;
715  while (arch) {
716  if (arch->clone.type != art->item->type)
717  arch = get_next_archetype(arch);
718 
719  for (allowed = art->allowed; allowed != NULL; allowed = allowed->next) {
720  if (strcmp(arch->name, allowed->name + 1) == 0) {
721  break;
722  }
723  }
724  if (allowed != NULL)
725  continue;
726 
727  if (arch->clone.face == NULL)
728  continue;
729  return arch->clone.face->number;
730  }
731  return (unsigned)-1;
732  } else {
733  const archetype *arch = find_archetype(art->allowed->name);
734  if (arch != NULL)
735  return arch->clone.face->number;
736  return (unsigned)-1;
737  }
738  }
739 
740  while (arch != NULL) {
741  if (arch->clone.type == art->item->type && arch->clone.face != NULL)
742  return arch->clone.face->number;
743 
744  arch = get_next_archetype(arch);
745  }
746  return (unsigned)-1;
747 }
EXTERN FILE * logfile
Definition: global.h:137
#define KEY_FACE_SUFFIX
Definition: artifact.c:281
static artifactlist * find_artifactlist_internal(int type)
Definition: artifact.c:530
#define FLAG_SEE_IN_DARK
Definition: define.h:338
#define FLAG_DAMNED
Definition: define.h:318
#define MAP_STYLE
Definition: map.h:98
#define LO_LINEMODE
Definition: loader.h:16
void object_give_identified_properties(object *op)
Definition: item.c:1324
#define SET_FLAG(xyz, p)
Definition: define.h:223
sstring add_refcount(sstring str)
Definition: shstr.c:210
const artifactlist * find_artifactlist(int type)
Definition: artifact.c:644
#define FABS(x)
Definition: define.h:22
unsigned artifact_get_face(const artifact *art)
Definition: artifact.c:706
unsigned char uint8_t
Definition: win32.h:161
StringBuffer * buf
Definition: readable.c:1591
#define FLAG_STAND_STILL
Definition: define.h:309
const Face * blank_face
Definition: image.c:35
archetype * find_archetype(const char *name)
Definition: assets.cpp:251
void fatal(enum fatal_error err)
Definition: utils.c:597
struct artifactstruct * items
Definition: artifact.h:30
Definition: face.h:14
void free_string(sstring str)
Definition: shstr.c:280
#define HUGE_BUF
Definition: define.h:37
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4136
const char * name
Definition: face.h:19
#define FLAG_CONFUSED
Definition: define.h:312
#define FLAG_STEALTH
Definition: define.h:313
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:314
static void free_artifactlist(artifactlist *al)
Definition: artifact.c:125
#define KEY_ANIMATION_SUFFIX
Definition: artifact.c:282
const Face * try_find_face(const char *name, const Face *error)
Definition: assets.cpp:283
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4259
void object_free_drop_inventory(object *ob)
Definition: object.c:1316
static artifactlist * get_empty_artifactlist(void)
Definition: artifact.c:39
sstring find_string(const char *str)
Definition: shstr.c:236
#define FLAG_CLIENT_ANIM_RANDOM
Definition: define.h:241
uint16_t total_chance
Definition: artifact.h:28
#define FLAG_ALIVE
Definition: define.h:230
#define FLAG_REFL_SPELL
Definition: define.h:275
int legal_artifact_combination(const object *op, const artifact *art)
Definition: artifact.c:221
int is_identified(const object *op)
Definition: item.c:1316
struct artifactliststruct * next
Definition: artifact.h:29
object * object_new(void)
Definition: object.c:1011
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2602
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
#define snprintf
Definition: win32.h:46
void dump_artifacts(void)
Definition: artifact.c:680
#define FLAG_NO_SAVE
Definition: define.h:244
uint8_t difficulty
Definition: artifact.h:17
const artifact * find_artifact(const object *op, const char *name)
Definition: artifact.c:654
struct linked_char * next
Definition: global.h:88
#define FLAG_IDENTIFIED
Definition: define.h:261
#define FOR_INV_FINISH()
Definition: define.h:714
void change_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:265
linked_char * allowed
Definition: artifact.h:19
void object_reset(object *op)
Definition: object.c:698
archetype * get_next_archetype(archetype *current)
Definition: assets.cpp:247
#define FLAG_XRAYS
Definition: define.h:301
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
EXTERN artifactlist * first_artifactlist
Definition: global.h:118
#define ARTIFACT_TRIES
Definition: artifact.c:146
#define MAX_BUF
Definition: define.h:35
void generate_artifact(object *op, int difficulty)
Definition: artifact.c:155
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.c:203
unsigned short uint16_t
Definition: win32.h:163
void free_all_artifacts(void)
Definition: artifact.c:140
EXTERN long nrofartifacts
Definition: global.h:140
const char * sstring
Definition: global.h:40
#define FLAG_CURSED
Definition: define.h:317
EXTERN long nrofallowedstr
Definition: global.h:141
#define FLAG_ANIMATE
Definition: define.h:242
static void free_artifact(artifact *at)
Definition: artifact.c:95
const char * name
Definition: global.h:87
static void free_charlinks(linked_char *lc)
Definition: artifact.c:77
#define FLAG_BLIND
Definition: define.h:337
#define RANDOM()
Definition: define.h:681
Animations * try_find_animation(const char *name)
Definition: assets.cpp:271
sstring name
Definition: face.h:26
int load_object(FILE *fp, object *op, int bufstate, int map_flags)
int allowed_size
Definition: artifact.h:20
static void compute_face_name(char *buf, size_t size, const char *name, const char *suffix)
Definition: artifact.c:260
static artifact * get_empty_artifact(void)
Definition: artifact.c:58
#define NROFATTACKS
Definition: attack.h:17
#define FLAG_LIFESAVE
Definition: define.h:306
void add_abilities(object *op, const object *change)
Definition: artifact.c:288
#define FLAG_MAKE_INVIS
Definition: define.h:329
void init_artifacts(FILE *file, const char *filename)
Definition: artifact.c:543
sstring add_string(const char *str)
Definition: shstr.c:124
int artifact_init
Definition: artifact.c:28
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:824
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
void set_abs_magic(object *op, int magic)
Definition: treasure.c:601
void object_set_msg(object *op, const char *msg)
Definition: object.c:4570
object * item
Definition: artifact.h:15
uint16_t chance
Definition: artifact.h:16
#define FLAG_REFL_MISSILE
Definition: define.h:273
void object_free_key_values(object *op)
Definition: object.c:718
void object_update_speed(object *op)
Definition: object.c:1086
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.c:370
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
void object_remove(object *op)
Definition: object.c:1588
struct artifactstruct * next
Definition: artifact.h:18