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