Crossfire Server, Trunk  R213250
treasure.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 
26 #define TREASURE_DEBUG
27 
28 #include "global.h"
29 
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "loader.h"
35 #include "sproto.h"
36 #include "treasure.h"
37 
44 static int resist_table[] = {
50 };
51 
53 #define num_resist_table 19
54 
55 static void change_treasure(treasure *t, object *op); /* overrule default values */
56 static int special_potion(object *op);
57 static void fix_flesh_item(object *item, const object *donor);
58 
59 extern const char *const spell_mapping[];
60 
65  if (ring_arch == NULL)
66  ring_arch = find_archetype("ring");
67  if (amulet_arch == NULL)
68  amulet_arch = find_archetype("amulet");
69  if (crown_arch == NULL)
70  crown_arch = find_archetype("crown");
71 }
72 
84  treasurelist *tl = (treasurelist *)malloc(sizeof(treasurelist));
85  if (tl == NULL)
87  memset(tl, 0, sizeof(treasurelist));
88  return tl;
89 }
90 
102  treasure *t = (treasure *)calloc(1, sizeof(treasure));
103  if (t == NULL)
105  t->item = NULL;
106  t->name = NULL;
107  t->next = NULL;
108  t->next_yes = NULL;
109  t->next_no = NULL;
110  t->chance = 100;
111  t->magic = 0;
112  t->nrof = 0;
113  return t;
114 }
115 
130 static treasure *load_treasure(FILE *fp, int *line) {
131  char buf[MAX_BUF], *cp, variable[MAX_BUF];
133  int value;
134 
135  nroftreasures++;
136  while (fgets(buf, MAX_BUF, fp) != NULL) {
137  (*line)++;
138 
139  if (*buf == '#')
140  continue;
141  if ((cp = strchr(buf, '\n')) != NULL)
142  *cp = '\0';
143  cp = buf;
144  while (isspace(*cp)) /* Skip blanks */
145  cp++;
146 
147  if (sscanf(cp, "arch %s", variable)) {
148  if ((t->item = find_archetype(variable)) == NULL) {
149  LOG(llevError, "Treasure lacks archetype: %s\n", variable);
151  }
152  } else if (sscanf(cp, "list %s", variable))
153  t->name = add_string(variable);
154  else if (sscanf(cp, "change_name %s", variable))
155  t->change_arch.name = add_string(variable);
156  else if (sscanf(cp, "change_title %s", variable))
157  t->change_arch.title = add_string(variable);
158  else if (sscanf(cp, "change_slaying %s", variable))
159  t->change_arch.slaying = add_string(variable);
160  else if (sscanf(cp, "chance %d", &value))
161  t->chance = (uint8_t)value;
162  else if (sscanf(cp, "nrof %d", &value))
163  t->nrof = (uint16_t)value;
164  else if (sscanf(cp, "magic %d", &value))
165  t->magic = (uint8_t)value;
166  else if (!strcmp(cp, "yes"))
167  t->next_yes = load_treasure(fp, line);
168  else if (!strcmp(cp, "no"))
169  t->next_no = load_treasure(fp, line);
170  else if (!strcmp(cp, "end"))
171  return t;
172  else if (!strcmp(cp, "more")) {
173  t->next = load_treasure(fp, line);
174  return t;
175  } else
176  LOG(llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, t->name ? t->name : "null", *line);
177  }
178  LOG(llevError, "treasure lacks 'end'.\n");
180  return t;
181 }
182 
183 #ifdef TREASURE_DEBUG
184 
195 static void check_treasurelist(const treasure *t, const treasurelist *tl) {
196  if (t->item == NULL && t->name == NULL)
197  LOG(llevError, "Treasurelist %s has element with no name or archetype\n", tl->name);
198  if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
199  LOG(llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", tl->name);
200  /* find_treasurelist will print out its own error message */
201  if (t->name && strcmp(t->name, "NONE"))
203  if (t->next)
204  check_treasurelist(t->next, tl);
205  if (t->next_yes)
207  if (t->next_no)
208  check_treasurelist(t->next_no, tl);
209 }
210 #endif
211 
219 void load_treasures(void) {
220  FILE *fp;
221  char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF];
222  treasurelist *previous = NULL;
223  treasure *t;
224  int line = 0;
225 
226  snprintf(filename, sizeof(filename), "%s/%s", settings.datadir, settings.treasures);
227  if ((fp = fopen(filename, "r")) == NULL) {
228  LOG(llevError, "Can't open treasure file.\n");
229  return;
230  }
231  while (fgets(buf, MAX_BUF, fp) != NULL) {
232  line++;
233  if (*buf == '#')
234  continue;
235 
236  if (sscanf(buf, "treasureone %s\n", name) || sscanf(buf, "treasure %s\n", name)) {
238 
239  tl->name = add_string(name);
240  if (previous == NULL)
241  first_treasurelist = tl;
242  else
243  previous->next = tl;
244  previous = tl;
245  tl->items = load_treasure(fp, &line);
246 
247  /* This is a one of the many items on the list should be generated.
248  * Add up the chance total, and check to make sure the yes & no
249  * fields of the treasures are not being used.
250  */
251  if (!strncmp(buf, "treasureone", 11)) {
252  for (t = tl->items; t != NULL; t = t->next) {
253 #ifdef TREASURE_DEBUG
254  if (t->next_yes || t->next_no) {
255  LOG(llevError, "Treasure %s is one item, but on treasure %s\n", tl->name, t->item ? t->item->name : t->name);
256  LOG(llevError, " the next_yes or next_no field is set\n");
257  }
258 #endif
259  tl->total_chance += t->chance;
260  }
261  }
262  } else
263  LOG(llevError, "Treasure-list didn't understand: %s, line %d\n", buf, line);
264  }
265  fclose(fp);
266 
267 #ifdef TREASURE_DEBUG
268  /* Perform some checks on how valid the treasure data actually is.
269  * verify that list transitions work (ie, the list that it is supposed
270  * to transition to exists). Also, verify that at least the name
271  * or archetype is set for each treasure element.
272  */
273  for (previous = first_treasurelist; previous != NULL; previous = previous->next)
274  check_treasurelist(previous->items, previous);
275 #endif
276 }
277 
290 treasurelist *find_treasurelist(const char *name) {
291  const char *tmp = find_string(name);
292  treasurelist *tl;
293 
294  /* Special cases - randomitems of none is to override default. If
295  * first_treasurelist is null, it means we are on the first pass of
296  * of loading archetyps, so for now, just return - second pass will
297  * init these values.
298  */
299  if (!strcmp(name, "none") || (!first_treasurelist))
300  return NULL;
301  if (tmp != NULL)
302  for (tl = first_treasurelist; tl != NULL; tl = tl->next)
303  if (tmp == tl->name)
304  return tl;
305  LOG(llevError, "Couldn't find treasurelist %s\n", name);
306  return NULL;
307 }
308 
309 
321 static void put_treasure(object *op, object *creator, int flags) {
322  /* Bit of a hack - spells should never be put onto the map. The entire
323  * treasure stuff is a problem - there is no clear idea of knowing
324  * this is the original object, or if this is an object that should be created
325  * by another object.
326  */
327  if (flags&GT_ENVIRONMENT && op->type != SPELL) {
329  object_insert_in_map_at(op, creator->map, op, INS_NO_MERGE|INS_NO_WALK_ON, creator->x, creator->y);
330  } else
331  op = object_insert_in_ob(op, creator);
332 }
333 
344 static void change_treasure(treasure *t, object *op) {
345  /* CMD: change_name xxxx */
346  if (t->change_arch.name) {
348  /* not great, but better than something that is completely wrong */
350  }
351 
352  if (t->change_arch.title) {
353  if (op->title)
354  free_string(op->title);
355  op->title = add_string(t->change_arch.title);
356  }
357 
358  if (t->change_arch.slaying) {
359  if (op->slaying)
360  free_string(op->slaying);
362  }
363 }
364 
380 static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries) {
381  object *tmp;
382 
383  if ((int)t->chance >= 100 || (RANDOM()%100+1) < t->chance) {
384  if (t->name) {
385  if (strcmp(t->name, "NONE") && difficulty >= t->magic)
386  create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries);
387  } else {
388  if (t->item->clone.invisible != 0 || !(flag&GT_INVISIBLE)) {
389  tmp = arch_to_object(t->item);
390  if (t->nrof && tmp->nrof <= 1)
391  tmp->nrof = RANDOM()%((int)t->nrof)+1;
392  fix_generated_item(tmp, op, difficulty, t->magic, flag);
393  change_treasure(t, tmp);
394  put_treasure(tmp, op, flag);
395  }
396  }
397  if (t->next_yes != NULL)
398  create_all_treasures(t->next_yes, op, flag, difficulty, tries);
399  } else
400  if (t->next_no != NULL)
401  create_all_treasures(t->next_no, op, flag, difficulty, tries);
402  if (t->next != NULL)
403  create_all_treasures(t->next, op, flag, difficulty, tries);
404 }
405 
424 static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries) {
425  int value = RANDOM()%tl->total_chance;
426  treasure *t;
427 
428  if (tries++ > 100) {
429  LOG(llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
430  return;
431  }
432 
433  for (t = tl->items; t != NULL; t = t->next) {
434  value -= t->chance;
435  if (value < 0)
436  break;
437  }
438 
439  if (!t || value >= 0) {
440  LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n");
441  abort();
442  return;
443  }
444  if (t->name) {
445  if (!strcmp(t->name, "NONE"))
446  return;
447  if (difficulty >= t->magic)
448  create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries);
449  else if (t->nrof)
450  create_one_treasure(tl, op, flag, difficulty, tries);
451  return;
452  }
453  if ((t->item) && (flag&GT_ONLY_GOOD)) { /* Generate only good items, damnit !*/
454  if (QUERY_FLAG(&(t->item->clone), FLAG_CURSED)
455  || QUERY_FLAG(&(t->item->clone), FLAG_DAMNED)) {
456  create_one_treasure(tl, op, flag, difficulty, tries+1);
457  return;
458  }
459  }
460  if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) {
461  object *tmp = arch_to_object(t->item);
462 
463  if (!tmp)
464  return;
465  if (t->nrof && tmp->nrof <= 1)
466  tmp->nrof = RANDOM()%((int)t->nrof)+1;
467  fix_generated_item(tmp, op, difficulty, t->magic, flag);
468  change_treasure(t, tmp);
469  put_treasure(tmp, op, flag);
470  }
471 }
472 
488 void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries) {
489  if (tries++ > 100) {
490  LOG(llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
491  return;
492  }
493  if (t->total_chance)
494  create_one_treasure(t, op, flag, difficulty, tries);
495  else
496  create_all_treasures(t->items, op, flag, difficulty, tries);
497 }
498 
516 object *generate_treasure(treasurelist *t, int difficulty) {
517  object *ob = object_new(), *tmp;
518 
519  create_treasure(t, ob, 0, difficulty, 0);
520 
521  /* Don't want to free the object we are about to return */
522  tmp = ob->inv;
523  if (tmp != NULL)
524  object_remove(tmp);
525  if (ob->inv) {
526  LOG(llevError, "In generate treasure, created multiple objects.\n");
527  }
529  return tmp;
530 }
531 
546 static int level_for_item(const object *op, int difficulty, int retmult) {
547  int level, mult, olevel;
548 
549  if (!op->inv) {
550  LOG(llevError, "level_for_item: Object %s has no inventory!\n", op->name);
551  return 0;
552  }
553  level = op->inv->level;
554 
555  /* Basically, we set mult to the lowest spell increase attribute that is
556  * not zero - zero's mean no modification is done, so we don't want those.
557  * given we want non zero results, we can't just use a few MIN's here.
558  */
559  mult = op->inv->dam_modifier;
560  if (op->inv->range_modifier && (op->inv->range_modifier < mult || mult == 0))
561  mult = op->inv->range_modifier;
562  if (op->inv->duration_modifier && (op->inv->duration_modifier < mult || mult == 0))
563  mult = op->inv->duration_modifier;
564 
565  if (mult == 0)
566  mult = 5;
567 
568  if (retmult)
569  return mult;
570 
571  olevel = mult*rndm(0, difficulty)+level;
572  if (olevel > MAX_SPELLITEM_LEVEL)
573  olevel = MAX_SPELLITEM_LEVEL;
574 
575  return olevel;
576 }
577 
585 static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1] = {
586 /*chance of magic difficulty*/
587 /* +0 +1 +2 +3 +4 */
588  { 94, 3, 2, 1, 0 }, /*1*/
589  { 94, 3, 2, 1, 0 }, /*2*/
590  { 94, 3, 2, 1, 0 }, /*3*/
591  { 94, 3, 2, 1, 0 }, /*4*/
592  { 94, 3, 2, 1, 0 }, /*5*/
593  { 90, 4, 3, 2, 1 }, /*6*/
594  { 90, 4, 3, 2, 1 }, /*7*/
595  { 90, 4, 3, 2, 1 }, /*8*/
596  { 90, 4, 3, 2, 1 }, /*9*/
597  { 90, 4, 3, 2, 1 }, /*10*/
598  { 85, 6, 4, 3, 2 }, /*11*/
599  { 85, 6, 4, 3, 2 }, /*12*/
600  { 85, 6, 4, 3, 2 }, /*13*/
601  { 85, 6, 4, 3, 2 }, /*14*/
602  { 85, 6, 4, 3, 2 }, /*15*/
603  { 81, 8, 5, 4, 3 }, /*16*/
604  { 81, 8, 5, 4, 3 }, /*17*/
605  { 81, 8, 5, 4, 3 }, /*18*/
606  { 81, 8, 5, 4, 3 }, /*19*/
607  { 81, 8, 5, 4, 3 }, /*20*/
608  { 75, 10, 6, 5, 4 }, /*21*/
609  { 75, 10, 6, 5, 4 }, /*22*/
610  { 75, 10, 6, 5, 4 }, /*23*/
611  { 75, 10, 6, 5, 4 }, /*24*/
612  { 75, 10, 6, 5, 4 }, /*25*/
613  { 70, 12, 7, 6, 5 }, /*26*/
614  { 70, 12, 7, 6, 5 }, /*27*/
615  { 70, 12, 7, 6, 5 }, /*28*/
616  { 70, 12, 7, 6, 5 }, /*29*/
617  { 70, 12, 7, 6, 5 }, /*30*/
618  { 70, 9, 8, 7, 6 }, /*31*/
619  { 70, 9, 8, 7, 6 }, /*32*/
620  { 70, 9, 8, 7, 6 }, /*33*/
621  { 70, 9, 8, 7, 6 }, /*34*/
622  { 70, 9, 8, 7, 6 }, /*35*/
623  { 70, 6, 9, 8, 7 }, /*36*/
624  { 70, 6, 9, 8, 7 }, /*37*/
625  { 70, 6, 9, 8, 7 }, /*38*/
626  { 70, 6, 9, 8, 7 }, /*39*/
627  { 70, 6, 9, 8, 7 }, /*40*/
628  { 70, 3, 10, 9, 8 }, /*41*/
629  { 70, 3, 10, 9, 8 }, /*42*/
630  { 70, 3, 10, 9, 8 }, /*43*/
631  { 70, 3, 10, 9, 8 }, /*44*/
632  { 70, 3, 10, 9, 8 }, /*45*/
633  { 70, 2, 9, 10, 9 }, /*46*/
634  { 70, 2, 9, 10, 9 }, /*47*/
635  { 70, 2, 9, 10, 9 }, /*48*/
636  { 70, 2, 9, 10, 9 }, /*49*/
637  { 70, 2, 9, 10, 9 }, /*50*/
638  { 70, 2, 7, 11, 10 }, /*51*/
639  { 70, 2, 7, 11, 10 }, /*52*/
640  { 70, 2, 7, 11, 10 }, /*53*/
641  { 70, 2, 7, 11, 10 }, /*54*/
642  { 70, 2, 7, 11, 10 }, /*55*/
643  { 70, 2, 5, 12, 11 }, /*56*/
644  { 70, 2, 5, 12, 11 }, /*57*/
645  { 70, 2, 5, 12, 11 }, /*58*/
646  { 70, 2, 5, 12, 11 }, /*59*/
647  { 70, 2, 5, 12, 11 }, /*60*/
648  { 70, 2, 3, 13, 12 }, /*61*/
649  { 70, 2, 3, 13, 12 }, /*62*/
650  { 70, 2, 3, 13, 12 }, /*63*/
651  { 70, 2, 3, 13, 12 }, /*64*/
652  { 70, 2, 3, 13, 12 }, /*65*/
653  { 70, 2, 3, 12, 13 }, /*66*/
654  { 70, 2, 3, 12, 13 }, /*67*/
655  { 70, 2, 3, 12, 13 }, /*68*/
656  { 70, 2, 3, 12, 13 }, /*69*/
657  { 70, 2, 3, 12, 13 }, /*70*/
658  { 70, 2, 3, 11, 14 }, /*71*/
659  { 70, 2, 3, 11, 14 }, /*72*/
660  { 70, 2, 3, 11, 14 }, /*73*/
661  { 70, 2, 3, 11, 14 }, /*74*/
662  { 70, 2, 3, 11, 14 }, /*75*/
663  { 70, 2, 3, 10, 15 }, /*76*/
664  { 70, 2, 3, 10, 15 }, /*77*/
665  { 70, 2, 3, 10, 15 }, /*78*/
666  { 70, 2, 3, 10, 15 }, /*79*/
667  { 70, 2, 3, 10, 15 }, /*80*/
668  { 70, 2, 3, 9, 16 }, /*81*/
669  { 70, 2, 3, 9, 16 }, /*82*/
670  { 70, 2, 3, 9, 16 }, /*83*/
671  { 70, 2, 3, 9, 16 }, /*84*/
672  { 70, 2, 3, 9, 16 }, /*85*/
673  { 70, 2, 3, 8, 17 }, /*86*/
674  { 70, 2, 3, 8, 17 }, /*87*/
675  { 70, 2, 3, 8, 17 }, /*88*/
676  { 70, 2, 3, 8, 17 }, /*89*/
677  { 70, 2, 3, 8, 17 }, /*90*/
678  { 70, 2, 3, 7, 18 }, /*91*/
679  { 70, 2, 3, 7, 18 }, /*92*/
680  { 70, 2, 3, 7, 18 }, /*93*/
681  { 70, 2, 3, 7, 18 }, /*94*/
682  { 70, 2, 3, 7, 18 }, /*95*/
683  { 70, 2, 3, 6, 19 }, /*96*/
684  { 70, 2, 3, 6, 19 }, /*97*/
685  { 70, 2, 3, 6, 19 }, /*98*/
686  { 70, 2, 3, 6, 19 }, /*99*/
687  { 70, 2, 3, 6, 19 }, /*100*/
688  { 70, 2, 3, 6, 19 }, /*101*/
689  { 70, 2, 3, 6, 19 }, /*101*/
690  { 70, 2, 3, 6, 19 }, /*102*/
691  { 70, 2, 3, 6, 19 }, /*103*/
692  { 70, 2, 3, 6, 19 }, /*104*/
693  { 70, 2, 3, 6, 19 }, /*105*/
694  { 70, 2, 3, 6, 19 }, /*106*/
695  { 70, 2, 3, 6, 19 }, /*107*/
696  { 70, 2, 3, 6, 19 }, /*108*/
697  { 70, 2, 3, 6, 19 }, /*109*/
698  { 70, 2, 3, 6, 19 }, /*110*/
699  { 70, 2, 3, 6, 19 }, /*111*/
700  { 70, 2, 3, 6, 19 }, /*112*/
701  { 70, 2, 3, 6, 19 }, /*113*/
702  { 70, 2, 3, 6, 19 }, /*114*/
703  { 70, 2, 3, 6, 19 }, /*115*/
704  { 70, 2, 3, 6, 19 }, /*116*/
705  { 70, 2, 3, 6, 19 }, /*117*/
706  { 70, 2, 3, 6, 19 }, /*118*/
707  { 70, 2, 3, 6, 19 }, /*119*/
708  { 70, 2, 3, 6, 19 }, /*120*/
709  { 70, 2, 3, 6, 19 }, /*121*/
710  { 70, 2, 3, 6, 19 }, /*122*/
711  { 70, 2, 3, 6, 19 }, /*123*/
712  { 70, 2, 3, 6, 19 }, /*124*/
713  { 70, 2, 3, 6, 19 }, /*125*/
714  { 70, 2, 3, 6, 19 }, /*126*/
715  { 70, 2, 3, 6, 19 }, /*127*/
716  { 70, 2, 3, 6, 19 }, /*128*/
717  { 70, 2, 3, 6, 19 }, /*129*/
718  { 70, 2, 3, 6, 19 }, /*130*/
719  { 70, 2, 3, 6, 19 }, /*131*/
720  { 70, 2, 3, 6, 19 }, /*132*/
721  { 70, 2, 3, 6, 19 }, /*133*/
722  { 70, 2, 3, 6, 19 }, /*134*/
723  { 70, 2, 3, 6, 19 }, /*135*/
724  { 70, 2, 3, 6, 19 }, /*136*/
725  { 70, 2, 3, 6, 19 }, /*137*/
726  { 70, 2, 3, 6, 19 }, /*138*/
727  { 70, 2, 3, 6, 19 }, /*139*/
728  { 70, 2, 3, 6, 19 }, /*140*/
729  { 70, 2, 3, 6, 19 }, /*141*/
730  { 70, 2, 3, 6, 19 }, /*142*/
731  { 70, 2, 3, 6, 19 }, /*143*/
732  { 70, 2, 3, 6, 19 }, /*144*/
733  { 70, 2, 3, 6, 19 }, /*145*/
734  { 70, 2, 3, 6, 19 }, /*146*/
735  { 70, 2, 3, 6, 19 }, /*147*/
736  { 70, 2, 3, 6, 19 }, /*148*/
737  { 70, 2, 3, 6, 19 }, /*149*/
738  { 70, 2, 3, 6, 19 }, /*150*/
739  { 70, 2, 3, 6, 19 }, /*151*/
740  { 70, 2, 3, 6, 19 }, /*152*/
741  { 70, 2, 3, 6, 19 }, /*153*/
742  { 70, 2, 3, 6, 19 }, /*154*/
743  { 70, 2, 3, 6, 19 }, /*155*/
744  { 70, 2, 3, 6, 19 }, /*156*/
745  { 70, 2, 3, 6, 19 }, /*157*/
746  { 70, 2, 3, 6, 19 }, /*158*/
747  { 70, 2, 3, 6, 19 }, /*159*/
748  { 70, 2, 3, 6, 19 }, /*160*/
749  { 70, 2, 3, 6, 19 }, /*161*/
750  { 70, 2, 3, 6, 19 }, /*162*/
751  { 70, 2, 3, 6, 19 }, /*163*/
752  { 70, 2, 3, 6, 19 }, /*164*/
753  { 70, 2, 3, 6, 19 }, /*165*/
754  { 70, 2, 3, 6, 19 }, /*166*/
755  { 70, 2, 3, 6, 19 }, /*167*/
756  { 70, 2, 3, 6, 19 }, /*168*/
757  { 70, 2, 3, 6, 19 }, /*169*/
758  { 70, 2, 3, 6, 19 }, /*170*/
759  { 70, 2, 3, 6, 19 }, /*171*/
760  { 70, 2, 3, 6, 19 }, /*172*/
761  { 70, 2, 3, 6, 19 }, /*173*/
762  { 70, 2, 3, 6, 19 }, /*174*/
763  { 70, 2, 3, 6, 19 }, /*175*/
764  { 70, 2, 3, 6, 19 }, /*176*/
765  { 70, 2, 3, 6, 19 }, /*177*/
766  { 70, 2, 3, 6, 19 }, /*178*/
767  { 70, 2, 3, 6, 19 }, /*179*/
768  { 70, 2, 3, 6, 19 }, /*180*/
769  { 70, 2, 3, 6, 19 }, /*181*/
770  { 70, 2, 3, 6, 19 }, /*182*/
771  { 70, 2, 3, 6, 19 }, /*183*/
772  { 70, 2, 3, 6, 19 }, /*184*/
773  { 70, 2, 3, 6, 19 }, /*185*/
774  { 70, 2, 3, 6, 19 }, /*186*/
775  { 70, 2, 3, 6, 19 }, /*187*/
776  { 70, 2, 3, 6, 19 }, /*188*/
777  { 70, 2, 3, 6, 19 }, /*189*/
778  { 70, 2, 3, 6, 19 }, /*190*/
779  { 70, 2, 3, 6, 19 }, /*191*/
780  { 70, 2, 3, 6, 19 }, /*192*/
781  { 70, 2, 3, 6, 19 }, /*193*/
782  { 70, 2, 3, 6, 19 }, /*194*/
783  { 70, 2, 3, 6, 19 }, /*195*/
784  { 70, 2, 3, 6, 19 }, /*196*/
785  { 70, 2, 3, 6, 19 }, /*197*/
786  { 70, 2, 3, 6, 19 }, /*198*/
787  { 70, 2, 3, 6, 19 }, /*199*/
788  { 70, 2, 3, 6, 19 }, /*200*/
789 };
790 
798 static int magic_from_difficulty(int difficulty) {
799  int percent, loop;
800 
801  difficulty--;
802  if (difficulty < 0)
803  difficulty = 0;
804 
805  if (difficulty >= DIFFLEVELS)
806  difficulty = DIFFLEVELS-1;
807 
808  percent = RANDOM()%100;
809 
810  for (loop = 0; loop < (MAXMAGIC+1); ++loop) {
811  percent -= difftomagic_list[difficulty][loop];
812  if (percent < 0)
813  break;
814  }
815  if (loop == (MAXMAGIC+1)) {
816  LOG(llevError, "Warning, table for difficulty %d bad.\n", difficulty);
817  loop = 0;
818  }
819  /* LOG(llevDebug, "Chose magic %d for difficulty %d\n", loop, difficulty);*/
820  return (RANDOM()%3) ? loop : -loop;
821 }
822 
834 void set_abs_magic(object *op, int magic) {
835  if (!magic)
836  return;
837 
838  op->magic = magic;
839  if (op->arch) {
840  if (op->type == ARMOUR)
841  ARMOUR_SPEED(op) = (ARMOUR_SPEED(&op->arch->clone)*(100+magic*10))/100;
842 
843  if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */
844  magic = (-magic);
845  op->weight = (op->arch->clone.weight*(100-magic*10))/100;
846  } else {
847  if (op->type == ARMOUR)
848  ARMOUR_SPEED(op) = (ARMOUR_SPEED(op)*(100+magic*10))/100;
849  if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */
850  magic = (-magic);
851  op->weight = (op->weight*(100-magic*10))/100;
852  }
853 }
854 
870 static void set_magic(int difficulty, object *op, int max_magic, int flags) {
871  int i;
872 
873  i = magic_from_difficulty(difficulty);
874  if ((flags&GT_ONLY_GOOD) && i < 0)
875  i = -i;
876  if (i > max_magic)
877  i = max_magic;
878  set_abs_magic(op, i);
879  if (i < 0)
880  SET_FLAG(op, FLAG_CURSED);
881 }
882 
899 static void set_ring_bonus(object *op, int bonus) {
900  int r = RANDOM()%(bonus > 0 ? 25 : 11);
901 
902  if (op->type == AMULET) {
903  if (!(RANDOM()%21))
904  r = 20+RANDOM()%2;
905  else {
906  if (RANDOM()&2)
907  r = 10;
908  else
909  r = 11+RANDOM()%9;
910  }
911  }
912 
913  switch (r) {
914  /* Redone by MSW 2000-11-26 to have much less code. Also,
915  * bonuses and penalties will stack and add to existing values.
916  * of the item.
917  */
918  case 0:
919  case 1:
920  case 2:
921  case 3:
922  case 4:
923  case 5:
924  case 6:
925  set_attr_value(&op->stats, r, (signed char)(bonus+get_attr_value(&op->stats, r)));
926  break;
927 
928  case 7:
929  op->stats.dam += bonus;
930  break;
931 
932  case 8:
933  op->stats.wc += bonus;
934  break;
935 
936  case 9:
937  op->stats.food += bonus; /* hunger/sustenance */
938  break;
939 
940  case 10:
941  op->stats.ac += bonus;
942  break;
943 
944  /* Item that gives protections/vulnerabilities */
945  case 11:
946  case 12:
947  case 13:
948  case 14:
949  case 15:
950  case 16:
951  case 17:
952  case 18:
953  case 19: {
954  int b = 5+FABS(bonus), val, resist = RANDOM()%num_resist_table;
955 
956  /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
957  val = 10+RANDOM()%b+RANDOM()%b+RANDOM()%b+RANDOM()%b;
958 
959  /* Cursed items need to have higher negative values to equal out with
960  * positive values for how protections work out. Put another
961  * little random element in since that they don't always end up with
962  * even values.
963  */
964  if (bonus < 0)
965  val = 2*-val-RANDOM()%b;
966  if (val > 35)
967  val = 35; /* Upper limit */
968  b = 0;
969  while (op->resist[resist_table[resist]] != 0 && b++ < 4) {
970  resist = RANDOM()%num_resist_table;
971  }
972  if (b == 4)
973  return; /* Not able to find a free resistance */
974  op->resist[resist_table[resist]] = val;
975  /* We should probably do something more clever here to adjust value
976  * based on how good a resistance we gave.
977  */
978  break;
979  }
980 
981  case 20:
982  if (op->type == AMULET) {
984  op->value *= 11;
985  } else {
986  op->stats.hp = 1; /* regenerate hit points */
987  op->value *= 4;
988  }
989  break;
990 
991  case 21:
992  if (op->type == AMULET) {
994  op->value *= 9;
995  } else {
996  op->stats.sp = 1; /* regenerate spell points */
997  op->value *= 3;
998  }
999  break;
1000 
1001  case 22:
1002  op->stats.exp += bonus; /* Speed! */
1003  op->value = (op->value*2)/3;
1004  break;
1005  }
1006  if (bonus > 0)
1007  op->value *= 2*bonus;
1008  else
1009  op->value = -(op->value*2*bonus)/3;
1010 }
1011 
1020 static int get_magic(int diff) {
1021  int i;
1022 
1023  if (diff < 3)
1024  diff = 3;
1025  for (i = 0; i < 4; i++)
1026  if (RANDOM()%diff)
1027  return i;
1028  return 4;
1029 }
1030 
1041 static void trap_adjust(object *trap, int difficulty) {
1042  int i;
1043 
1044  /* now we set the trap level to match the difficulty of the level
1045  * the formula below will give a level from 1 to (2*difficulty) with
1046  * a peak probability at difficulty
1047  */
1048 
1049  trap->level = rndm(0, difficulty-1)+rndm(0, difficulty-1);
1050  if (trap->level < 1)
1051  trap->level = 1;
1052 
1053  /* set the hiddenness of the trap, similar formula to above */
1054  trap->stats.Cha = rndm(0, 19)+rndm(0, difficulty-1)+rndm(0, difficulty-1);
1055 
1056  if (!trap->other_arch && !trap->inv) {
1057  /* set the damage of the trap.
1058  * we get 0-4 pts of damage per level of difficulty of the map in
1059  * the trap
1060  */
1061 
1062  trap->stats.dam = 0;
1063  for (i = 0; i < difficulty; i++)
1064  trap->stats.dam += rndm(0, 4);
1065 
1066  /* the poison trap special case */
1067  if (trap->attacktype&AT_POISON) {
1068  trap->stats.dam = rndm(0, difficulty-1);
1069  if (trap->stats.dam < 1)
1070  trap->stats.dam = 1;
1071  }
1072 
1073  /* so we get an appropriate amnt of exp for AT_DEATH traps */
1074  if (trap->attacktype&AT_DEATH)
1075  trap->stats.dam = 127;
1076  }
1077 }
1078 
1079 #define DICE2 (get_magic(2) == 2 ? 2 : 1)
1080 #define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3)
1081 
1108 void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags) {
1109  int was_magic = op->magic, num_enchantments = 0, save_item_power;
1110 
1111  if (!creator || creator->type == op->type)
1112  creator = op; /* safety & to prevent polymorphed objects giving attributes */
1113 
1114  /* If we make an artifact, this information will be destroyed */
1115  save_item_power = op->item_power;
1116  op->item_power = 0;
1117 
1118  if (op->randomitems && op->type != SPELL) {
1119  create_treasure(op->randomitems, op, flags, difficulty, 0);
1120  if (!op->inv)
1121  LOG(llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->name);
1122  /* So the treasure doesn't get created again */
1123  op->randomitems = NULL;
1124  }
1125 
1126  if (difficulty < 1)
1127  difficulty = 1;
1128  if (!(flags&GT_MINIMAL)) {
1129  if (op->arch == crown_arch) {
1130  set_magic(difficulty > 25 ? 30 : difficulty+5, op, max_magic, flags);
1131  num_enchantments = calc_item_power(op);
1132  generate_artifact(op, difficulty);
1133  } else {
1134  if (!op->magic && max_magic)
1135  set_magic(difficulty, op, max_magic, flags);
1136  num_enchantments = calc_item_power(op);
1137  if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT))
1138  || op->type == ROD
1139  || difficulty >= 999)
1140  generate_artifact(op, difficulty);
1141  }
1142 
1143  /* Object was made an artifact. Calculate its item_power rating.
1144  * the item_power in the object is what the artifact adds.
1145  */
1146  if (op->title) {
1147  /* if save_item_power is set, then most likely we started with an
1148  * artifact and have added new abilities to it - this is rare, but
1149  * but I have seen things like 'strange rings of fire'. So just
1150  * figure out the power from the base power plus what this one adds.
1151  * Note that since item_power is not quite linear, this actually
1152  * ends up being somewhat of a bonus.
1153  */
1154  if (save_item_power)
1155  op->item_power = save_item_power+get_power_from_ench(op->item_power);
1156  else
1157  op->item_power += get_power_from_ench(num_enchantments);
1158  } else if (save_item_power) {
1159  /* restore the item_power field to the object if we haven't changed
1160  * it. we don't care about num_enchantments - that will basically
1161  * just have calculated some value from the base attributes of the
1162  * archetype.
1163  */
1164  op->item_power = save_item_power;
1165  } else {
1166  /* item_power was zero. This is suspicious, as it may be because it
1167  * was never previously calculated. Let's compute a value and see if
1168  * it is non-zero. If it indeed is, then assign it as the new
1169  * item_power value.
1170  * - gros, 21th of July 2006.
1171  */
1172  op->item_power = calc_item_power(op);
1173  save_item_power = op->item_power; /* Just in case it would get used
1174  * again below */
1175  }
1176  } else {
1177  /* If flag is GT_MINIMAL, we want to restore item power */
1178  op->item_power = save_item_power;
1179  }
1180 
1181  /* materialtype modifications. Note we allow this on artifacts. */
1182  set_materialname(op);
1183 
1184  if (flags&GT_MINIMAL) {
1185  if (op->type == POTION)
1186  /* Handle healing and magic power potions */
1187  if (op->stats.sp && !op->randomitems) {
1188  object *tmp;
1189 
1190  tmp = create_archetype(spell_mapping[op->stats.sp]);
1191  object_insert_in_ob(tmp, op);
1192  op->stats.sp = 0;
1193  }
1194  } else if (!op->title) { /* Only modify object if not special */
1195  switch (op->type) {
1196  case WEAPON:
1197  case ARMOUR:
1198  case SHIELD:
1199  case HELMET:
1200  case CLOAK:
1201  if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4))
1202  set_ring_bonus(op, -DICE2);
1203  break;
1204 
1205  case BRACERS:
1206  if (!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED) ? 5 : 20))) {
1208  if (!QUERY_FLAG(op, FLAG_CURSED))
1209  op->value *= 3;
1210  }
1211  break;
1212 
1213  case POTION: {
1214  int too_many_tries = 0, is_special = 0;
1215 
1216  /* Handle healing and magic power potions */
1217  if (op->stats.sp && !op->randomitems) {
1218  object *tmp;
1219 
1220  tmp = create_archetype(spell_mapping[op->stats.sp]);
1221  object_insert_in_ob(tmp, op);
1222  op->stats.sp = 0;
1223  }
1224 
1225  while (!(is_special = special_potion(op)) && !op->inv) {
1226  generate_artifact(op, difficulty);
1227  if (too_many_tries++ > 10)
1228  break;
1229  }
1230  /* don't want to change value for healing/magic power potions,
1231  * since the value set on those is already correct.
1232  */
1233  if (op->inv && op->randomitems) {
1234  /* value multiplier is same as for scrolls */
1235  op->value = (op->value*op->inv->value);
1236  op->level = op->inv->level/2+RANDOM()%difficulty+RANDOM()%difficulty;
1237  } else {
1238  FREE_AND_COPY(op->name, "potion");
1239  FREE_AND_COPY(op->name_pl, "potions");
1240  }
1241  if (!(flags&GT_ONLY_GOOD) && RANDOM()%2)
1242  SET_FLAG(op, FLAG_CURSED);
1243  break;
1244  }
1245 
1246  case AMULET:
1247  if (op->arch == amulet_arch)
1248  op->value *= 5; /* Since it's not just decoration */
1249  /* fall through */
1250  case RING:
1251  if (op->arch == NULL) {
1252  object_remove(op);
1254  op = NULL;
1255  break;
1256  }
1257  if (op->arch != ring_arch && op->arch != amulet_arch)
1258  /* It's a special artifact!*/
1259  break;
1260 
1261  if (GET_ANIM_ID(op))
1262  SET_ANIMATION(op, RANDOM()%((int)NUM_ANIMATIONS(op)));
1263  if (!(flags&GT_ONLY_GOOD) && !(RANDOM()%3))
1264  SET_FLAG(op, FLAG_CURSED);
1266  if (op->type != RING) /* Amulets have only one ability */
1267  break;
1268  if (!(RANDOM()%4)) {
1269  int d = (RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1270  if (d > 0)
1271  op->value *= 3;
1272  set_ring_bonus(op, d);
1273  if (!(RANDOM()%4)) {
1274  int d = (RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1275  if (d > 0)
1276  op->value *= 5;
1277  set_ring_bonus(op, d);
1278  }
1279  }
1280  break;
1281 
1282  case BOOK:
1283  /* Is it an empty book?, if yes lets make a special
1284  * msg for it, and tailor its properties based on the
1285  * creator and/or map level we found it on.
1286  */
1287  if (!op->msg && RANDOM()%10) {
1288  /* set the book level properly */
1289  if (creator->level == 0 || QUERY_FLAG(creator, FLAG_ALIVE)) {
1290  if (op->map && op->map->difficulty)
1291  op->level = RANDOM()%(op->map->difficulty)+RANDOM()%10+1;
1292  else
1293  op->level = RANDOM()%20+1;
1294  } else
1295  op->level = RANDOM()%creator->level;
1296 
1297  tailor_readable_ob(op, creator->stats.sp);
1298  /* books w/ info are worth more! */
1299  if (op->msg != NULL)
1300  op->value *= ((op->level > 10 ? op->level : (op->level+1)/2)*((strlen(op->msg)/250)+1));
1301  /* creator related stuff */
1302 
1303  if (creator->slaying && !op->slaying) /* for check_inv floors */
1304  op->slaying = add_string(creator->slaying);
1305 
1306  /* add exp so reading it gives xp (once)*/
1307  op->stats.exp = op->value > 10000 ? op->value/5 : op->value/10;
1308  }
1309  /* for library, chained books. Note that some monsters have
1310  * no_pick set - we don't want to set no pick in that case. */
1311  if (QUERY_FLAG(creator, FLAG_NO_PICK)
1312  && !QUERY_FLAG(creator, FLAG_MONSTER))
1313  SET_FLAG(op, FLAG_NO_PICK);
1314  break;
1315 
1316  case SPELLBOOK:
1317  op->value = op->value*op->inv->value;
1318  /* add exp so learning gives xp */
1319  op->level = op->inv->level;
1320  op->stats.exp = op->value;
1321  /* some more fun */
1322  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 5) {
1323  if (rndm(1, 6) <= 1)
1324  SET_FLAG(op, FLAG_DAMNED);
1325  else
1326  SET_FLAG(op, FLAG_CURSED);
1327  } else if (rndm(1, 100) <= 1) {
1328  SET_FLAG(op, FLAG_BLESSED);
1329  }
1330  break;
1331 
1332  case WAND:
1333  /* nrof in the treasure list is number of charges,
1334  * not number of wands. So copy that into food (charges),
1335  * and reset nrof.
1336  */
1337  op->stats.food = op->inv->nrof;
1338  op->nrof = 1;
1339  /* If the spell changes by level, choose a random level
1340  * for it, and adjust price. If the spell doesn't
1341  * change by level, just set the wand to the level of
1342  * the spell, and value calculation is simpler.
1343  */
1344  if (op->inv->duration_modifier
1345  || op->inv->dam_modifier
1346  || op->inv->range_modifier) {
1347  op->level = level_for_item(op, difficulty, 0);
1348  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1349  } else {
1350  op->level = op->inv->level;
1351  op->value = op->value*op->inv->value;
1352  }
1353  break;
1354 
1355  case ROD:
1356  op->level = level_for_item(op, difficulty, 0);
1357  rod_adjust(op);
1358  break;
1359 
1360  case SCROLL:
1361  op->level = level_for_item(op, difficulty, 0);
1362  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1363  /* add exp so reading them properly gives xp */
1364  op->stats.exp = op->value/5;
1365  op->nrof = op->inv->nrof;
1366  /* some more fun */
1367  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 20) {
1368  if (rndm(1, 6) <= 1)
1369  SET_FLAG(op, FLAG_DAMNED);
1370  else
1371  SET_FLAG(op, FLAG_CURSED);
1372  } else if (rndm(1, 100) <= 2) {
1373  SET_FLAG(op, FLAG_BLESSED);
1374  }
1375  break;
1376 
1377  case RUNE:
1378  trap_adjust(op, difficulty);
1379  break;
1380 
1381  case TRAP:
1382  trap_adjust(op, difficulty);
1383  break;
1384  } /* switch type */
1385  }
1386  if (flags&GT_STARTEQUIP) {
1387  if (op->nrof < 2
1388  && op->type != CONTAINER
1389  && op->type != MONEY
1390  && !QUERY_FLAG(op, FLAG_IS_THROWN))
1392  else if (op->type != MONEY)
1393  op->value = 0;
1394  }
1395 
1396  if (!(flags&GT_ENVIRONMENT))
1397  fix_flesh_item(op, creator);
1398 }
1399 
1403 static void dump_monster_treasure_rec(const char *name, treasure *t, int depth) {
1404  treasurelist *tl;
1405  int i;
1406 
1407  if (depth > 100)
1408  return;
1409 
1410  while (t != NULL) {
1411  if (t->name != NULL) {
1412  for (i = 0; i < depth; i++)
1413  fprintf(logfile, " ");
1414  fprintf(logfile, "{ (list: %s)\n", t->name);
1415  tl = find_treasurelist(t->name);
1416  dump_monster_treasure_rec(name, tl->items, depth+2);
1417  for (i = 0; i < depth; i++)
1418  fprintf(logfile, " ");
1419  fprintf(logfile, "} (end of list: %s)\n", t->name);
1420  } else {
1421  for (i = 0; i < depth; i++)
1422  fprintf(logfile, " ");
1423  if (t->item->clone.type == FLESH)
1424  fprintf(logfile, "%s's %s\n", name, t->item->clone.name);
1425  else
1426  fprintf(logfile, "%s\n", t->item->clone.name);
1427  }
1428  if (t->next_yes != NULL) {
1429  for (i = 0; i < depth; i++)
1430  fprintf(logfile, " ");
1431  fprintf(logfile, " (if yes)\n");
1432  dump_monster_treasure_rec(name, t->next_yes, depth+1);
1433  }
1434  if (t->next_no != NULL) {
1435  for (i = 0; i < depth; i++)
1436  fprintf(logfile, " ");
1437  fprintf(logfile, " (if no)\n");
1438  dump_monster_treasure_rec(name, t->next_no, depth+1);
1439  }
1440  t = t->next;
1441  }
1442 }
1443 
1448 void dump_monster_treasure(const char *name) {
1449  archetype *at;
1450  int found;
1451 
1452  found = 0;
1453  fprintf(logfile, "\n");
1454  for (at = first_archetype; at != NULL; at = at->next)
1455  if (!strcasecmp(at->clone.name, name) && at->clone.title == NULL) {
1456  fprintf(logfile, "treasures for %s (arch: %s)\n", at->clone.name, at->name);
1457  if (at->clone.randomitems != NULL)
1459  else
1460  fprintf(logfile, "(nothing)\n");
1461  fprintf(logfile, "\n");
1462  found++;
1463  }
1464  if (found == 0)
1465  fprintf(logfile, "No objects have the name %s!\n\n", name);
1466 }
1467 
1475 static void fix_flesh_item(object *item, const object *donor) {
1476  char tmpbuf[MAX_BUF];
1477  int i;
1478 
1479  if (item->type == FLESH && donor && QUERY_FLAG(donor, FLAG_MONSTER)) {
1480  /* change the name */
1481  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name);
1482  FREE_AND_COPY(item->name, tmpbuf);
1483  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name_pl);
1484  FREE_AND_COPY(item->name_pl, tmpbuf);
1485 
1486  /* store original arch in other_arch */
1487  if (!item->other_arch) {
1488  if (!donor->arch->reference_count) {
1489  item->other_arch = donor->arch;
1490  } else {
1491  /* If dealing with custom monsters, other_arch still needs to
1492  * point back to the original. Otherwise what happens
1493  * is that other_arch points at the custom archetype, but
1494  * that can be freed. Reference count doesn't work because
1495  * the loader will not be able to resolve the other_arch at
1496  * load time (server may has restarted, etc.)
1497  */
1498  archetype *original = find_archetype(donor->arch->name);
1499 
1500  if (original)
1501  item->other_arch = original;
1502  else {
1503  LOG(llevError, "could not find original archetype %s for custom monster!\n", donor->arch->name);
1504  abort();
1505  }
1506  }
1507  }
1508 
1509  /* weight is FLESH weight/100 * donor */
1510  if ((item->weight = (signed long)(((double)item->weight/(double)100.0)*(double)donor->weight)) == 0)
1511  item->weight = 1;
1512 
1513  /* value is multiplied by level of donor */
1514  item->value *= isqrt(donor->level*2);
1515 
1516  /* food value */
1517  item->stats.food += (donor->stats.hp/100)+donor->stats.Con;
1518 
1519  /* flesh items inherit some abilities of donor, but not full effect. */
1520  for (i = 0; i < NROFATTACKS; i++)
1521  item->resist[i] = donor->resist[i]/2;
1522 
1523  /* item inherits donor's level and exp (important for dragons) */
1524  item->level = donor->level;
1525  item->stats.exp = donor->stats.exp;
1526 
1527  /* if donor has some attacktypes, the flesh is poisonous */
1528  if (donor->attacktype&AT_POISON)
1529  item->type = POISON;
1530  if (donor->attacktype&AT_ACID)
1531  item->stats.hp = -1*item->stats.food;
1532  SET_FLAG(item, FLAG_NO_STEAL);
1533 
1534  /* attempt to change the face - will take a face named "donor's arch"_"item's face". We ignore the animation for now */
1535  if (item->face != NULL) {
1536  unsigned int face;
1537  snprintf(tmpbuf, sizeof(tmpbuf), "%s_%s", donor->arch->name, item->face->name);
1538  face = find_face(tmpbuf, (unsigned int) -1);
1539  if (face != (unsigned int)-1) {
1540  item->face = &new_faces[face];
1541  }
1542  }
1543  }
1544 }
1545 
1554 static int special_potion(object *op) {
1555  int i;
1556 
1557  if (op->attacktype)
1558  return 1;
1559 
1560  if (op->stats.Str
1561  || op->stats.Dex
1562  || op->stats.Con
1563  || op->stats.Pow
1564  || op->stats.Wis
1565  || op->stats.Int
1566  || op->stats.Cha)
1567  return 1;
1568 
1569  for (i = 0; i < NROFATTACKS; i++)
1570  if (op->resist[i])
1571  return 1;
1572 
1573  return 0;
1574 }
1575 
1583  if (t->next)
1585  if (t->next_yes)
1587  if (t->next_no)
1589  free(t);
1590 }
1591 
1592 
1597  treasurelist *tl, *next;
1598 
1599  for (tl = first_treasurelist; tl != NULL; tl = next) {
1600  next = tl->next;
1601  if (tl->name)
1602  free_string(tl->name);
1603  if (tl->items)
1605  free(tl);
1606  }
1607 }
1608 
1629 static objectlink *treasure_find_matching_type(treasure *t, int type, objectlink *olp, int tries)
1630 {
1631 
1632  objectlink *nolp = olp;
1633 
1634  /* I do not think this should get logged - since we are processing all
1635  * possibilities, this could happen pretty often.
1636  */
1637  if (tries++ > 100) {
1638  return olp;
1639  }
1640 
1641  if (t->name) {
1642  if (strcmp(t->name, "NONE")) {
1643  /* Look up treasurelist and then process - this is safer
1644  * as if for some reason the treasurelist does not exist,
1645  * this will just skip over it harmlessly.
1646  */
1648 
1649  if (tl)
1650  nolp = treasure_find_matching_type(tl->items, type, nolp, tries);
1651  }
1652  } else {
1653  if (t->item->clone.type == type) {
1654  nolp = get_objectlink();
1655  nolp->next = olp;
1656  nolp->ob = &t->item->clone;
1657  }
1658  }
1659  if (t->next_yes != NULL) {
1660  nolp = treasure_find_matching_type(t->next_yes, type, nolp, tries);
1661  }
1662  if (t->next_no != NULL) {
1663  nolp = treasure_find_matching_type(t->next_no, type, nolp, tries);
1664  }
1665  if (t->next != NULL) {
1666  nolp = treasure_find_matching_type(t->next, type, nolp, tries);
1667  }
1668  return nolp;
1669 }
1670 
1706 objectlink * treasurelist_find_matching_type(const treasurelist *randomitems, int type, int traverse) {
1707 
1708  objectlink *olp;
1709 
1710  olp=treasure_find_matching_type(randomitems->items, type, NULL, 0);
1711 
1712  return olp;
1713 
1714 }
1715 
EXTERN FILE * logfile
Definition: global.h:142
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:219
int reference_count
Definition: object.h:475
int8_t Int
Definition: living.h:36
archetype * find_archetype(const char *name)
Definition: arch.c:695
#define FLAG_DAMNED
Definition: define.h:318
int8_t ac
Definition: living.h:38
uint8_t dam_modifier
Definition: object.h:409
Definition: object.h:185
static void free_treasurestruct(treasure *t)
Definition: treasure.c:1582
const char *const spell_mapping[]
Definition: object.h:444
#define ATNR_TURN_UNDEAD
Definition: attack.h:62
const char * name
Definition: treasure.h:52
struct _change_arch change_arch
Definition: treasure.h:69
#define SET_FLAG(xyz, p)
Definition: define.h:223
#define MAXMAGIC
Definition: treasure.h:13
int get_power_from_ench(int ench)
Definition: item.c:229
#define FABS(x)
Definition: define.h:22
unsigned char uint8_t
Definition: win32.h:161
Definition: object.h:221
New_Face * new_faces
Definition: image.c:33
Definition: object.h:204
static void trap_adjust(object *trap, int difficulty)
Definition: treasure.c:1041
void fatal(enum fatal_error err)
Definition: utils.c:597
#define ATNR_DEPLETE
Definition: attack.h:65
treasurelist * find_treasurelist(const char *name)
Definition: treasure.c:290
void free_string(sstring str)
Definition: shstr.c:280
#define SET_ANIMATION(ob, newanim)
Definition: global.h:169
Definition: object.h:137
struct treasureliststruct * randomitems
Definition: object.h:387
object clone
Definition: object.h:472
#define ATNR_SLOW
Definition: attack.h:60
struct treasureliststruct * next
Definition: treasure.h:89
int16_t invisible
Definition: object.h:361
uint8_t duration_modifier
Definition: object.h:406
Definition: object.h:240
Definition: object.h:119
int isqrt(int n)
Definition: utils.c:586
Definition: object.h:136
const char * slaying
Definition: object.h:319
static int level_for_item(const object *op, int difficulty, int retmult)
Definition: treasure.c:546
Definition: object.h:109
int64_t exp
Definition: living.h:47
#define FLAG_BLESSED
Definition: define.h:378
Definition: object.h:139
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:314
int16_t sp
Definition: living.h:42
Definition: object.h:187
static objectlink * treasure_find_matching_type(treasure *t, int type, objectlink *olp, int tries)
Definition: treasure.c:1629
struct archt * other_arch
Definition: object.h:415
const char * treasures
Definition: global.h:254
#define ATNR_CONFUSION
Definition: attack.h:54
Definition: object.h:467
Definition: object.h:220
struct archt * item
Definition: treasure.h:64
int8_t Con
Definition: living.h:36
#define num_resist_table
Definition: treasure.c:53
int16_t hp
Definition: living.h:40
static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:380
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:488
static int get_magic(int diff)
Definition: treasure.c:1020
object * ob
Definition: object.h:445
int rndm(int min, int max)
Definition: utils.c:162
int16_t total_chance
Definition: treasure.h:84
Definition: object.h:241
void object_free_drop_inventory(object *ob)
Definition: object.c:1389
const char * name
Definition: face.h:20
const char * title
Definition: object.h:317
int16_t y
Definition: object.h:326
EXTERN archetype * amulet_arch
Definition: global.h:160
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1933
sstring find_string(const char *str)
Definition: shstr.c:236
#define FLAG_ALIVE
Definition: define.h:230
#define FLAG_REFL_SPELL
Definition: define.h:275
static int resist_table[]
Definition: treasure.c:44
Definition: object.h:114
object * object_new(void)
Definition: object.c:1068
const char * name_pl
Definition: object.h:315
object * create_archetype(const char *name)
Definition: arch.c:620
#define FLAG_OBJ_ORIGINAL
Definition: define.h:365
#define DIFFLEVELS
Definition: treasure.h:16
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2707
static void change_treasure(treasure *t, object *op)
Definition: treasure.c:344
#define ATNR_PARALYZE
Definition: attack.h:61
#define FLAG_NO_STEAL
Definition: define.h:343
int32_t weight
Definition: object.h:366
void free_all_treasures(void)
Definition: treasure.c:1596
static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1]
Definition: treasure.c:585
uint8_t range_modifier
Definition: object.h:408
int8_t Wis
Definition: living.h:36
#define CHANCE_FOR_ARTIFACT
Definition: treasure.h:10
static int special_potion(object *op)
Definition: treasure.c:1554
#define MAX_SPELLITEM_LEVEL
Definition: treasure.h:19
struct mapdef * map
Definition: object.h:297
#define ATNR_LIFE_STEALING
Definition: attack.h:73
#define ATNR_DEATH
Definition: attack.h:66
#define snprintf
Definition: win32.h:46
static void check_treasurelist(const treasure *t, const treasurelist *tl)
Definition: treasure.c:195
int16_t dam
Definition: living.h:46
#define ATNR_BLIND
Definition: attack.h:71
const char * name
Definition: object.h:311
const char * title
Definition: treasure.h:53
#define ARMOUR_SPEED(xyz)
Definition: define.h:482
#define ATNR_FEAR
Definition: attack.h:63
void load_treasures(void)
Definition: treasure.c:219
uint8_t magic
Definition: treasure.h:71
#define INS_NO_WALK_ON
Definition: object.h:570
void tailor_readable_ob(object *book, int msg_type)
Definition: readable.c:2044
uint32_t nrof
Definition: object.h:333
int8_t Cha
Definition: living.h:36
#define ATNR_MAGIC
Definition: attack.h:50
static treasurelist * get_empty_treasurelist(void)
Definition: treasure.c:83
static treasure * load_treasure(FILE *fp, int *line)
Definition: treasure.c:130
Definition: object.h:111
int8_t item_power
Definition: object.h:363
#define ATNR_HOLYWORD
Definition: attack.h:70
EXTERN treasurelist * first_treasurelist
Definition: global.h:120
#define ATNR_PHYSICAL
Definition: attack.h:49
struct treasurestruct * next_no
Definition: treasure.h:68
#define ATNR_ELECTRICITY
Definition: attack.h:52
#define ATNR_POISON
Definition: attack.h:59
Definition: object.h:214
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.c:1108
#define MAX_BUF
Definition: define.h:35
void generate_artifact(object *op, int difficulty)
Definition: artifact.c:155
uint16_t nrof
Definition: treasure.h:76
int16_t x
Definition: object.h:326
struct treasurestruct * items
Definition: treasure.h:90
#define ATNR_DRAIN
Definition: attack.h:56
#define ATNR_GHOSTHIT
Definition: attack.h:58
int calc_item_power(const object *op)
Definition: item.c:247
int8_t wc
Definition: living.h:37
unsigned short uint16_t
Definition: win32.h:163
EXTERN archetype * crown_arch
Definition: global.h:160
#define FLAG_IS_THROWN
Definition: define.h:249
uint16_t difficulty
Definition: map.h:343
static void set_magic(int difficulty, object *op, int max_magic, int flags)
Definition: treasure.c:870
static const flag_definition flags[]
int8_t Str
Definition: living.h:36
int16_t resist[NROFATTACKS]
Definition: object.h:342
static void put_treasure(object *op, object *creator, int flags)
Definition: treasure.c:321
#define FLAG_CURSED
Definition: define.h:317
const char * datadir
Definition: global.h:248
Definition: object.h:113
Definition: object.h:135
#define AT_POISON
Definition: attack.h:86
uint8_t chance
Definition: treasure.h:70
const char * name
Definition: treasure.h:83
uint32_t attacktype
Definition: object.h:343
#define INS_NO_MERGE
Definition: object.h:568
struct treasurestruct * next_yes
Definition: treasure.h:67
#define RANDOM()
Definition: define.h:681
#define FREE_AND_COPY(sv, nv)
Definition: global.h:211
#define NUM_ANIMATIONS(ob)
Definition: global.h:177
living stats
Definition: object.h:369
int8_t Dex
Definition: living.h:36
struct archt * arch
Definition: object.h:414
struct oblnk * next
Definition: object.h:446
void dump_monster_treasure(const char *name)
Definition: treasure.c:1448
uint8_t type
Definition: object.h:339
struct Settings settings
Definition: init.c:39
objectlink * treasurelist_find_matching_type(const treasurelist *randomitems, int type, int traverse)
Definition: treasure.c:1706
static int magic_from_difficulty(int difficulty)
Definition: treasure.c:798
struct archt * next
Definition: object.h:469
#define NROFATTACKS
Definition: attack.h:17
const char * msg
Definition: object.h:322
#define FLAG_STARTEQUIP
Definition: define.h:268
#define GET_ANIM_ID(ob)
Definition: global.h:171
sstring add_string(const char *str)
Definition: shstr.c:124
#define DICE2
Definition: treasure.c:1079
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:256
const char * slaying
Definition: treasure.h:54
#define FLAG_MONSTER
Definition: define.h:245
int8_t Pow
Definition: living.h:36
struct obj * inv
Definition: object.h:290
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
EXTERN archetype * ring_arch
Definition: global.h:160
void set_abs_magic(object *op, int magic)
Definition: treasure.c:834
void set_materialname(object *op)
Definition: utils.c:301
#define ATNR_COLD
Definition: attack.h:53
void rod_adjust(object *rod)
Definition: main.c:362
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:516
static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:424
static void fix_flesh_item(object *item, const object *donor)
Definition: treasure.c:1475
const New_Face * face
Definition: object.h:332
static void set_ring_bonus(object *op, int bonus)
Definition: treasure.c:899
#define FLAG_NO_PICK
Definition: define.h:239
Definition: object.h:120
struct treasurestruct * next
Definition: treasure.h:66
#define FLAG_REFL_MISSILE
Definition: define.h:273
int16_t level
Definition: object.h:352
#define AT_ACID
Definition: attack.h:82
const char * name
Definition: treasure.h:65
void init_archetype_pointers(void)
Definition: treasure.c:64
#define ATNR_ACID
Definition: attack.h:55
unsigned find_face(const char *name, unsigned error)
Definition: image.c:303
#define AT_DEATH
Definition: attack.h:93
EXTERN archetype * first_archetype
Definition: global.h:122
object * arch_to_object(archetype *at)
Definition: arch.c:571
int32_t value
Definition: object.h:351
int8_t magic
Definition: object.h:349
const char * name
Definition: object.h:468
static treasure * get_empty_treasure(void)
Definition: treasure.c:101
void object_remove(object *op)
Definition: object.c:1666
static void dump_monster_treasure_rec(const char *name, treasure *t, int depth)
Definition: treasure.c:1403
int32_t food
Definition: living.h:48
#define ATNR_FIRE
Definition: attack.h:51
#define ATNR_DISEASE
Definition: attack.h:74
EXTERN long nroftreasures
Definition: global.h:145