Crossfire Server, Trunk
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 
20 #include "global.h"
21 
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 
27 #include "loader.h"
28 #include "sproto.h"
29 #include "treasure.h"
30 
37 static int resist_table[] = {
43 };
44 
46 #define num_resist_table 19
47 
48 static void change_treasure(treasure *t, object *op); /* overrule default values */
49 static int special_potion(object *op);
50 static void fix_flesh_item(object *item, const object *donor);
51 
56  if (ring_arch == NULL)
57  ring_arch = find_archetype("ring");
58  if (amulet_arch == NULL)
59  amulet_arch = find_archetype("amulet");
60  if (crown_arch == NULL)
61  crown_arch = find_archetype("crown");
62 }
63 
75 static void put_treasure(object *op, object *creator, int flags) {
76  /* Bit of a hack - spells should never be put onto the map. The entire
77  * treasure stuff is a problem - there is no clear idea of knowing
78  * this is the original object, or if this is an object that should be created
79  * by another object.
80  */
81  if (flags&GT_ENVIRONMENT && op->type != SPELL) {
83  object_insert_in_map_at(op, creator->map, op, INS_NO_MERGE|INS_NO_WALK_ON, creator->x, creator->y);
84  } else
85  object_insert_in_ob(op, creator);
86 }
87 
98 static void change_treasure(treasure *t, object *op) {
99  /* CMD: change_name xxxx */
100  if (t->change_arch.name) {
101  FREE_AND_COPY(op->name, t->change_arch.name);
102  /* not great, but better than something that is completely wrong */
103  FREE_AND_COPY(op->name_pl, t->change_arch.name);
104  }
105 
106  if (t->change_arch.title) {
107  if (op->title)
108  free_string(op->title);
109  op->title = add_string(t->change_arch.title);
110  }
111 
112  if (t->change_arch.slaying) {
113  if (op->slaying)
114  free_string(op->slaying);
115  op->slaying = add_string(t->change_arch.slaying);
116  }
117 }
118 
134 static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries) {
135  object *tmp;
136 
137  if ((int)t->chance >= 100 || (RANDOM()%100+1) < t->chance) {
138  if (t->name) {
139  if (strcmp(t->name, "NONE") && difficulty >= t->magic)
140  create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries);
141  } else {
142  if (t->item->clone.invisible != 0 || !(flag&GT_INVISIBLE)) {
143  tmp = arch_to_object(t->item);
144  if (t->nrof && tmp->nrof <= 1)
145  tmp->nrof = RANDOM()%((int)t->nrof)+1;
146  fix_generated_item(tmp, op, difficulty, t->magic, flag);
148  put_treasure(tmp, op, flag);
149  }
150  }
151  if (t->next_yes != NULL)
152  create_all_treasures(t->next_yes, op, flag, difficulty, tries);
153  } else
154  if (t->next_no != NULL)
155  create_all_treasures(t->next_no, op, flag, difficulty, tries);
156  if (t->next != NULL)
157  create_all_treasures(t->next, op, flag, difficulty, tries);
158 }
159 
178 static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries) {
179  int value = RANDOM()%tl->total_chance;
180  treasure *t;
181 
182  if (tries++ > 100) {
183  LOG(llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
184  return;
185  }
186 
187  for (t = tl->items; t != NULL; t = t->next) {
188  value -= t->chance;
189  if (value < 0)
190  break;
191  }
192 
193  if (!t || value >= 0) {
194  LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n");
195  abort();
196  return;
197  }
198  if (t->name) {
199  if (!strcmp(t->name, "NONE"))
200  return;
201  if (difficulty >= t->magic)
202  create_treasure(find_treasurelist(t->name), op, flag, difficulty, tries);
203  else if (t->nrof)
204  create_one_treasure(tl, op, flag, difficulty, tries);
205  return;
206  }
207  if ((t->item) && (flag&GT_ONLY_GOOD)) { /* Generate only good items, damnit !*/
208  if (QUERY_FLAG(&(t->item->clone), FLAG_CURSED)
209  || QUERY_FLAG(&(t->item->clone), FLAG_DAMNED)) {
210  create_one_treasure(tl, op, flag, difficulty, tries+1);
211  return;
212  }
213  }
214  if ((t->item && t->item->clone.invisible != 0) || flag != GT_INVISIBLE) {
215  object *tmp = arch_to_object(t->item);
216 
217  if (!tmp)
218  return;
219  if (t->nrof && tmp->nrof <= 1)
220  tmp->nrof = RANDOM()%((int)t->nrof)+1;
221  fix_generated_item(tmp, op, difficulty, t->magic, flag);
223  put_treasure(tmp, op, flag);
224  }
225 }
226 
242 void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries) {
243  if (tries++ > 100) {
244  LOG(llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
245  return;
246  }
247  if (!t->items) {
248  LOG(llevError, "Empty treasure list %s\n", t->name);
249  return;
250  }
251  if (t->total_chance)
252  create_one_treasure(t, op, flag, difficulty, tries);
253  else
254  create_all_treasures(t->items, op, flag, difficulty, tries);
255 }
256 
274 object *generate_treasure(treasurelist *t, int difficulty) {
275  object *ob = object_new(), *tmp;
276 
277  create_treasure(t, ob, 0, difficulty, 0);
278 
279  /* Don't want to free the object we are about to return */
280  tmp = ob->inv;
281  if (tmp != NULL)
283  if (ob->inv) {
284  LOG(llevError, "In generate treasure, created multiple objects.\n");
285  }
287  return tmp;
288 }
289 
302 static int level_for_item(const object *op, int difficulty) {
303  int level, mult, olevel;
304 
305  if (!op->inv) {
306  LOG(llevError, "level_for_item: Object %s has no inventory!\n", op->name);
307  return 0;
308  }
309  level = op->inv->level;
310 
311  /* Basically, we set mult to the lowest spell increase attribute that is
312  * not zero - zero's mean no modification is done, so we don't want those.
313  * given we want non zero results, we can't just use a few MIN's here.
314  */
315  mult = op->inv->dam_modifier;
316  if (op->inv->range_modifier && (op->inv->range_modifier < mult || mult == 0))
317  mult = op->inv->range_modifier;
318  if (op->inv->duration_modifier && (op->inv->duration_modifier < mult || mult == 0))
319  mult = op->inv->duration_modifier;
320 
321  if (mult == 0)
322  mult = 5;
323 
324  olevel = mult*rndm(0, difficulty)+level;
325  if (olevel > MAX_SPELLITEM_LEVEL)
326  olevel = MAX_SPELLITEM_LEVEL;
327 
328  return olevel;
329 }
330 
338 static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1] = {
339 /*chance of magic difficulty*/
340 /* +0 +1 +2 +3 +4 */
341  { 94, 3, 2, 1, 0 }, /*1*/
342  { 94, 3, 2, 1, 0 }, /*2*/
343  { 94, 3, 2, 1, 0 }, /*3*/
344  { 94, 3, 2, 1, 0 }, /*4*/
345  { 94, 3, 2, 1, 0 }, /*5*/
346  { 90, 4, 3, 2, 1 }, /*6*/
347  { 90, 4, 3, 2, 1 }, /*7*/
348  { 90, 4, 3, 2, 1 }, /*8*/
349  { 90, 4, 3, 2, 1 }, /*9*/
350  { 90, 4, 3, 2, 1 }, /*10*/
351  { 85, 6, 4, 3, 2 }, /*11*/
352  { 85, 6, 4, 3, 2 }, /*12*/
353  { 85, 6, 4, 3, 2 }, /*13*/
354  { 85, 6, 4, 3, 2 }, /*14*/
355  { 85, 6, 4, 3, 2 }, /*15*/
356  { 81, 8, 5, 4, 3 }, /*16*/
357  { 81, 8, 5, 4, 3 }, /*17*/
358  { 81, 8, 5, 4, 3 }, /*18*/
359  { 81, 8, 5, 4, 3 }, /*19*/
360  { 81, 8, 5, 4, 3 }, /*20*/
361  { 75, 10, 6, 5, 4 }, /*21*/
362  { 75, 10, 6, 5, 4 }, /*22*/
363  { 75, 10, 6, 5, 4 }, /*23*/
364  { 75, 10, 6, 5, 4 }, /*24*/
365  { 75, 10, 6, 5, 4 }, /*25*/
366  { 70, 12, 7, 6, 5 }, /*26*/
367  { 70, 12, 7, 6, 5 }, /*27*/
368  { 70, 12, 7, 6, 5 }, /*28*/
369  { 70, 12, 7, 6, 5 }, /*29*/
370  { 70, 12, 7, 6, 5 }, /*30*/
371  { 70, 9, 8, 7, 6 }, /*31*/
372  { 70, 9, 8, 7, 6 }, /*32*/
373  { 70, 9, 8, 7, 6 }, /*33*/
374  { 70, 9, 8, 7, 6 }, /*34*/
375  { 70, 9, 8, 7, 6 }, /*35*/
376  { 70, 6, 9, 8, 7 }, /*36*/
377  { 70, 6, 9, 8, 7 }, /*37*/
378  { 70, 6, 9, 8, 7 }, /*38*/
379  { 70, 6, 9, 8, 7 }, /*39*/
380  { 70, 6, 9, 8, 7 }, /*40*/
381  { 70, 3, 10, 9, 8 }, /*41*/
382  { 70, 3, 10, 9, 8 }, /*42*/
383  { 70, 3, 10, 9, 8 }, /*43*/
384  { 70, 3, 10, 9, 8 }, /*44*/
385  { 70, 3, 10, 9, 8 }, /*45*/
386  { 70, 2, 9, 10, 9 }, /*46*/
387  { 70, 2, 9, 10, 9 }, /*47*/
388  { 70, 2, 9, 10, 9 }, /*48*/
389  { 70, 2, 9, 10, 9 }, /*49*/
390  { 70, 2, 9, 10, 9 }, /*50*/
391  { 70, 2, 7, 11, 10 }, /*51*/
392  { 70, 2, 7, 11, 10 }, /*52*/
393  { 70, 2, 7, 11, 10 }, /*53*/
394  { 70, 2, 7, 11, 10 }, /*54*/
395  { 70, 2, 7, 11, 10 }, /*55*/
396  { 70, 2, 5, 12, 11 }, /*56*/
397  { 70, 2, 5, 12, 11 }, /*57*/
398  { 70, 2, 5, 12, 11 }, /*58*/
399  { 70, 2, 5, 12, 11 }, /*59*/
400  { 70, 2, 5, 12, 11 }, /*60*/
401  { 70, 2, 3, 13, 12 }, /*61*/
402  { 70, 2, 3, 13, 12 }, /*62*/
403  { 70, 2, 3, 13, 12 }, /*63*/
404  { 70, 2, 3, 13, 12 }, /*64*/
405  { 70, 2, 3, 13, 12 }, /*65*/
406  { 70, 2, 3, 12, 13 }, /*66*/
407  { 70, 2, 3, 12, 13 }, /*67*/
408  { 70, 2, 3, 12, 13 }, /*68*/
409  { 70, 2, 3, 12, 13 }, /*69*/
410  { 70, 2, 3, 12, 13 }, /*70*/
411  { 70, 2, 3, 11, 14 }, /*71*/
412  { 70, 2, 3, 11, 14 }, /*72*/
413  { 70, 2, 3, 11, 14 }, /*73*/
414  { 70, 2, 3, 11, 14 }, /*74*/
415  { 70, 2, 3, 11, 14 }, /*75*/
416  { 70, 2, 3, 10, 15 }, /*76*/
417  { 70, 2, 3, 10, 15 }, /*77*/
418  { 70, 2, 3, 10, 15 }, /*78*/
419  { 70, 2, 3, 10, 15 }, /*79*/
420  { 70, 2, 3, 10, 15 }, /*80*/
421  { 70, 2, 3, 9, 16 }, /*81*/
422  { 70, 2, 3, 9, 16 }, /*82*/
423  { 70, 2, 3, 9, 16 }, /*83*/
424  { 70, 2, 3, 9, 16 }, /*84*/
425  { 70, 2, 3, 9, 16 }, /*85*/
426  { 70, 2, 3, 8, 17 }, /*86*/
427  { 70, 2, 3, 8, 17 }, /*87*/
428  { 70, 2, 3, 8, 17 }, /*88*/
429  { 70, 2, 3, 8, 17 }, /*89*/
430  { 70, 2, 3, 8, 17 }, /*90*/
431  { 70, 2, 3, 7, 18 }, /*91*/
432  { 70, 2, 3, 7, 18 }, /*92*/
433  { 70, 2, 3, 7, 18 }, /*93*/
434  { 70, 2, 3, 7, 18 }, /*94*/
435  { 70, 2, 3, 7, 18 }, /*95*/
436  { 70, 2, 3, 6, 19 }, /*96*/
437  { 70, 2, 3, 6, 19 }, /*97*/
438  { 70, 2, 3, 6, 19 }, /*98*/
439  { 70, 2, 3, 6, 19 }, /*99*/
440  { 70, 2, 3, 6, 19 }, /*100*/
441  { 70, 2, 3, 6, 19 }, /*101*/
442  { 70, 2, 3, 6, 19 }, /*101*/
443  { 70, 2, 3, 6, 19 }, /*102*/
444  { 70, 2, 3, 6, 19 }, /*103*/
445  { 70, 2, 3, 6, 19 }, /*104*/
446  { 70, 2, 3, 6, 19 }, /*105*/
447  { 70, 2, 3, 6, 19 }, /*106*/
448  { 70, 2, 3, 6, 19 }, /*107*/
449  { 70, 2, 3, 6, 19 }, /*108*/
450  { 70, 2, 3, 6, 19 }, /*109*/
451  { 70, 2, 3, 6, 19 }, /*110*/
452  { 70, 2, 3, 6, 19 }, /*111*/
453  { 70, 2, 3, 6, 19 }, /*112*/
454  { 70, 2, 3, 6, 19 }, /*113*/
455  { 70, 2, 3, 6, 19 }, /*114*/
456  { 70, 2, 3, 6, 19 }, /*115*/
457  { 70, 2, 3, 6, 19 }, /*116*/
458  { 70, 2, 3, 6, 19 }, /*117*/
459  { 70, 2, 3, 6, 19 }, /*118*/
460  { 70, 2, 3, 6, 19 }, /*119*/
461  { 70, 2, 3, 6, 19 }, /*120*/
462  { 70, 2, 3, 6, 19 }, /*121*/
463  { 70, 2, 3, 6, 19 }, /*122*/
464  { 70, 2, 3, 6, 19 }, /*123*/
465  { 70, 2, 3, 6, 19 }, /*124*/
466  { 70, 2, 3, 6, 19 }, /*125*/
467  { 70, 2, 3, 6, 19 }, /*126*/
468  { 70, 2, 3, 6, 19 }, /*127*/
469  { 70, 2, 3, 6, 19 }, /*128*/
470  { 70, 2, 3, 6, 19 }, /*129*/
471  { 70, 2, 3, 6, 19 }, /*130*/
472  { 70, 2, 3, 6, 19 }, /*131*/
473  { 70, 2, 3, 6, 19 }, /*132*/
474  { 70, 2, 3, 6, 19 }, /*133*/
475  { 70, 2, 3, 6, 19 }, /*134*/
476  { 70, 2, 3, 6, 19 }, /*135*/
477  { 70, 2, 3, 6, 19 }, /*136*/
478  { 70, 2, 3, 6, 19 }, /*137*/
479  { 70, 2, 3, 6, 19 }, /*138*/
480  { 70, 2, 3, 6, 19 }, /*139*/
481  { 70, 2, 3, 6, 19 }, /*140*/
482  { 70, 2, 3, 6, 19 }, /*141*/
483  { 70, 2, 3, 6, 19 }, /*142*/
484  { 70, 2, 3, 6, 19 }, /*143*/
485  { 70, 2, 3, 6, 19 }, /*144*/
486  { 70, 2, 3, 6, 19 }, /*145*/
487  { 70, 2, 3, 6, 19 }, /*146*/
488  { 70, 2, 3, 6, 19 }, /*147*/
489  { 70, 2, 3, 6, 19 }, /*148*/
490  { 70, 2, 3, 6, 19 }, /*149*/
491  { 70, 2, 3, 6, 19 }, /*150*/
492  { 70, 2, 3, 6, 19 }, /*151*/
493  { 70, 2, 3, 6, 19 }, /*152*/
494  { 70, 2, 3, 6, 19 }, /*153*/
495  { 70, 2, 3, 6, 19 }, /*154*/
496  { 70, 2, 3, 6, 19 }, /*155*/
497  { 70, 2, 3, 6, 19 }, /*156*/
498  { 70, 2, 3, 6, 19 }, /*157*/
499  { 70, 2, 3, 6, 19 }, /*158*/
500  { 70, 2, 3, 6, 19 }, /*159*/
501  { 70, 2, 3, 6, 19 }, /*160*/
502  { 70, 2, 3, 6, 19 }, /*161*/
503  { 70, 2, 3, 6, 19 }, /*162*/
504  { 70, 2, 3, 6, 19 }, /*163*/
505  { 70, 2, 3, 6, 19 }, /*164*/
506  { 70, 2, 3, 6, 19 }, /*165*/
507  { 70, 2, 3, 6, 19 }, /*166*/
508  { 70, 2, 3, 6, 19 }, /*167*/
509  { 70, 2, 3, 6, 19 }, /*168*/
510  { 70, 2, 3, 6, 19 }, /*169*/
511  { 70, 2, 3, 6, 19 }, /*170*/
512  { 70, 2, 3, 6, 19 }, /*171*/
513  { 70, 2, 3, 6, 19 }, /*172*/
514  { 70, 2, 3, 6, 19 }, /*173*/
515  { 70, 2, 3, 6, 19 }, /*174*/
516  { 70, 2, 3, 6, 19 }, /*175*/
517  { 70, 2, 3, 6, 19 }, /*176*/
518  { 70, 2, 3, 6, 19 }, /*177*/
519  { 70, 2, 3, 6, 19 }, /*178*/
520  { 70, 2, 3, 6, 19 }, /*179*/
521  { 70, 2, 3, 6, 19 }, /*180*/
522  { 70, 2, 3, 6, 19 }, /*181*/
523  { 70, 2, 3, 6, 19 }, /*182*/
524  { 70, 2, 3, 6, 19 }, /*183*/
525  { 70, 2, 3, 6, 19 }, /*184*/
526  { 70, 2, 3, 6, 19 }, /*185*/
527  { 70, 2, 3, 6, 19 }, /*186*/
528  { 70, 2, 3, 6, 19 }, /*187*/
529  { 70, 2, 3, 6, 19 }, /*188*/
530  { 70, 2, 3, 6, 19 }, /*189*/
531  { 70, 2, 3, 6, 19 }, /*190*/
532  { 70, 2, 3, 6, 19 }, /*191*/
533  { 70, 2, 3, 6, 19 }, /*192*/
534  { 70, 2, 3, 6, 19 }, /*193*/
535  { 70, 2, 3, 6, 19 }, /*194*/
536  { 70, 2, 3, 6, 19 }, /*195*/
537  { 70, 2, 3, 6, 19 }, /*196*/
538  { 70, 2, 3, 6, 19 }, /*197*/
539  { 70, 2, 3, 6, 19 }, /*198*/
540  { 70, 2, 3, 6, 19 }, /*199*/
541  { 70, 2, 3, 6, 19 }, /*200*/
542 };
543 
551 static int magic_from_difficulty(int difficulty) {
552  int percent, loop;
553 
554  difficulty--;
555  if (difficulty < 0)
556  difficulty = 0;
557 
558  if (difficulty >= DIFFLEVELS)
559  difficulty = DIFFLEVELS-1;
560 
561  percent = RANDOM()%100;
562 
563  for (loop = 0; loop < (MAXMAGIC+1); ++loop) {
564  percent -= difftomagic_list[difficulty][loop];
565  if (percent < 0)
566  break;
567  }
568  if (loop == (MAXMAGIC+1)) {
569  LOG(llevError, "Warning, table for difficulty %d bad.\n", difficulty);
570  loop = 0;
571  }
572  /* LOG(llevDebug, "Chose magic %d for difficulty %d\n", loop, difficulty);*/
573  return (RANDOM()%3) ? loop : -loop;
574 }
575 
591 void set_abs_magic(object *op, int magic) {
592  int32_t base_weight, base_speed;
593  if (!magic)
594  return;
595 
596  op->magic = magic;
597  if (op->arch) {
598  base_weight = op->arch->clone.weight;
599  base_speed = ARMOUR_SPEED(&op->arch->clone);
600  }
601  else {
602  base_weight = op->weight;
603  base_speed = ARMOUR_SPEED(op);
604  }
605  // Now we do the calculations
606  if (op->type == ARMOUR) {
608  ARMOUR_SPEED(op) = base_speed*(100+magic*settings.armor_speed_improvement)/100;
609  else
610  // This could have been done with a loop, but that seems to be less scalable.
611  // This will introduce less roundoff error than a loop, anyway
612  ARMOUR_SPEED(op) = (int32_t)(base_speed * pow(((float)(100+settings.armor_speed_improvement))/100, magic));
613  }
614  // Prepare for handling the weight. Sometimes cursed ones will have low weight like good ones.
615  if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */
616  magic = (-magic);
618  op->weight = (base_weight*(100-magic*settings.armor_weight_reduction))/100;
619  else
620  op->weight = (int32_t)(base_weight * pow(((float)(100-settings.armor_weight_reduction))/100, magic));
621 
622 }
623 
639 static void set_magic(int difficulty, object *op, int max_magic, int flags) {
640  int i;
641 
642  i = magic_from_difficulty(difficulty);
643  if ((flags&GT_ONLY_GOOD) && i < 0)
644  i = -i;
645  if (i > max_magic)
646  i = max_magic;
647  set_abs_magic(op, i);
648  if (i < 0)
650 }
651 
668 static void set_ring_bonus(object *op, int bonus) {
669  int r = RANDOM()%(bonus > 0 ? 25 : 11);
670 
671  if (op->type == AMULET) {
672  if (!(RANDOM()%21))
673  r = 20+RANDOM()%2;
674  else {
675  if (RANDOM()&2)
676  r = 10;
677  else
678  r = 11+RANDOM()%9;
679  }
680  }
681 
682  switch (r) {
683  /* Redone by MSW 2000-11-26 to have much less code. Also,
684  * bonuses and penalties will stack and add to existing values.
685  * of the item.
686  */
687  case 0:
688  case 1:
689  case 2:
690  case 3:
691  case 4:
692  case 5:
693  case 6:
694  set_attr_value(&op->stats, r, (signed char)(bonus+get_attr_value(&op->stats, r)));
695  break;
696 
697  case 7:
698  op->stats.dam += bonus;
699  break;
700 
701  case 8:
702  op->stats.wc += bonus;
703  break;
704 
705  case 9:
706  op->stats.food += bonus; /* hunger/sustenance */
707  break;
708 
709  case 10:
710  op->stats.ac += bonus;
711  break;
712 
713  /* Item that gives protections/vulnerabilities */
714  case 11:
715  case 12:
716  case 13:
717  case 14:
718  case 15:
719  case 16:
720  case 17:
721  case 18:
722  case 19: {
723  int b = 5+FABS(bonus), val, resist = RANDOM()%num_resist_table;
724 
725  /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
726  val = 10+RANDOM()%b+RANDOM()%b+RANDOM()%b+RANDOM()%b;
727 
728  /* Cursed items need to have higher negative values to equal out with
729  * positive values for how protections work out. Put another
730  * little random element in since that they don't always end up with
731  * even values.
732  */
733  if (bonus < 0)
734  val = 2*-val-RANDOM()%b;
735  if (val > 35)
736  val = 35; /* Upper limit */
737  b = 0;
738  while (op->resist[resist_table[resist]] != 0 && b++ < 4) {
739  resist = RANDOM()%num_resist_table;
740  }
741  if (b == 4)
742  return; /* Not able to find a free resistance */
743  op->resist[resist_table[resist]] = val;
744  /* We should probably do something more clever here to adjust value
745  * based on how good a resistance we gave.
746  */
747  break;
748  }
749 
750  case 20:
751  if (op->type == AMULET) {
753  op->value *= 11;
754  } else {
755  op->stats.hp = 1; /* regenerate hit points */
756  op->value *= 4;
757  }
758  break;
759 
760  case 21:
761  if (op->type == AMULET) {
763  op->value *= 9;
764  } else {
765  op->stats.sp = 1; /* regenerate spell points */
766  op->value *= 3;
767  }
768  break;
769 
770  case 22:
771  op->stats.exp += bonus; /* Speed! */
772  op->value = (op->value*2)/3;
773  break;
774  }
775  if (bonus > 0)
776  op->value *= 2*bonus;
777  else
778  op->value = -(op->value*2*bonus)/3;
779 }
780 
789 static int get_magic(int diff) {
790  int i;
791 
792  if (diff < 3)
793  diff = 3;
794  for (i = 0; i < 4; i++)
795  if (RANDOM()%diff)
796  return i;
797  return 4;
798 }
799 
810 static void trap_adjust(object *trap, int difficulty) {
811  int i;
812 
813  /* now we set the trap level to match the difficulty of the level
814  * the formula below will give a level from 1 to (2*difficulty) with
815  * a peak probability at difficulty
816  */
817 
818  trap->level = rndm(0, difficulty-1)+rndm(0, difficulty-1);
819  if (trap->level < 1)
820  trap->level = 1;
821 
822  /* set the hiddenness of the trap, similar formula to above */
823  trap->stats.Cha = rndm(0, 19)+rndm(0, difficulty-1)+rndm(0, difficulty-1);
824 
825  if (!trap->other_arch && !trap->inv) {
826  /* set the damage of the trap.
827  * we get 0-4 pts of damage per level of difficulty of the map in
828  * the trap
829  */
830 
831  trap->stats.dam = 0;
832  for (i = 0; i < difficulty; i++)
833  trap->stats.dam += rndm(0, 4);
834 
835  /* the poison trap special case */
836  if (trap->attacktype&AT_POISON) {
837  trap->stats.dam = rndm(0, difficulty-1);
838  if (trap->stats.dam < 1)
839  trap->stats.dam = 1;
840  }
841 
842  /* so we get an appropriate amnt of exp for AT_DEATH traps */
843  if (trap->attacktype&AT_DEATH)
844  trap->stats.dam = 127;
845  }
846 }
847 
848 #define DICE2 (get_magic(2) == 2 ? 2 : 1)
849 #define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3)
850 
877 void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags) {
878  int was_magic = op->magic, num_enchantments = 0, save_item_power;
879 
880  if (!creator || creator->type == op->type)
881  creator = op; /* safety & to prevent polymorphed objects giving attributes */
882 
883  /* If we make an artifact, this information will be destroyed */
884  save_item_power = op->item_power;
885  op->item_power = 0;
886 
887  if (op->randomitems && op->type != SPELL) {
888  create_treasure(op->randomitems, op, flags, difficulty, 0);
889  if (!op->inv)
890  LOG(llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->name);
891  /* So the treasure doesn't get created again */
892  op->randomitems = NULL;
893  }
894 
895  if (difficulty < 1)
896  difficulty = 1;
897  if (!(flags&GT_MINIMAL)) {
898  if (op->arch == crown_arch) {
899  set_magic(difficulty > 25 ? 30 : difficulty+5, op, max_magic, flags);
900  num_enchantments = calc_item_power(op);
901  generate_artifact(op, difficulty);
902  } else {
903  if (!op->magic && max_magic)
904  set_magic(difficulty, op, max_magic, flags);
905  num_enchantments = calc_item_power(op);
906  if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT))
907  || op->type == ROD
908  || difficulty >= 999)
909  generate_artifact(op, difficulty);
910  }
911 
912  /* Object was made an artifact. Calculate its item_power rating.
913  * the item_power in the object is what the artifact adds.
914  */
915  if (op->title) {
916  /* if save_item_power is set, then most likely we started with an
917  * artifact and have added new abilities to it - this is rare, but
918  * but I have seen things like 'strange rings of fire'. So just
919  * figure out the power from the base power plus what this one adds.
920  * Note that since item_power is not quite linear, this actually
921  * ends up being somewhat of a bonus.
922  */
923  if (save_item_power)
924  op->item_power = save_item_power+get_power_from_ench(op->item_power);
925  else
926  op->item_power += get_power_from_ench(num_enchantments);
927  } else if (save_item_power) {
928  /* restore the item_power field to the object if we haven't changed
929  * it. we don't care about num_enchantments - that will basically
930  * just have calculated some value from the base attributes of the
931  * archetype.
932  */
933  op->item_power = save_item_power;
934  } else {
935  /* item_power was zero. This is suspicious, as it may be because it
936  * was never previously calculated. Let's compute a value and see if
937  * it is non-zero. If it indeed is, then assign it as the new
938  * item_power value.
939  * - gros, 21th of July 2006.
940  */
941  op->item_power = calc_item_power(op);
942  save_item_power = op->item_power; /* Just in case it would get used
943  * again below */
944  }
945  } else {
946  /* If flag is GT_MINIMAL, we want to restore item power */
947  op->item_power = save_item_power;
948  }
949 
950  /* materialtype modifications. Note we allow this on artifacts. */
952 
953  if (flags&GT_MINIMAL) {
954  if (op->type == POTION)
955  /* Handle healing and magic power potions */
956  if (op->stats.sp && !op->randomitems) {
957  object *tmp;
958  if (spell_mapping[op->stats.sp]) {
959  tmp = create_archetype(spell_mapping[op->stats.sp]);
961  }
962  op->stats.sp = 0;
963  }
964  } else if (!op->title) { /* Only modify object if not special */
965  switch (op->type) {
966  case WEAPON:
967  case ARMOUR:
968  case SHIELD:
969  case HELMET:
970  case CLOAK:
971  if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4))
973  break;
974 
975  case BRACERS:
976  if (!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED) ? 5 : 20))) {
978  if (!QUERY_FLAG(op, FLAG_CURSED))
979  op->value *= 3;
980  }
981  break;
982 
983  case POTION: {
984  int too_many_tries = 0, is_special = 0;
985 
986  /* Handle healing and magic power potions */
987  if (op->stats.sp && !op->randomitems) {
988  object *tmp;
989 
990  tmp = create_archetype(spell_mapping[op->stats.sp]);
992  op->stats.sp = 0;
993  }
994 
995  while (!(is_special = special_potion(op)) && !op->inv) {
996  generate_artifact(op, difficulty);
997  if (too_many_tries++ > 10)
998  break;
999  }
1000  /* don't want to change value for healing/magic power potions,
1001  * since the value set on those is already correct.
1002  */
1003  if (op->inv && op->randomitems) {
1004  /* value multiplier is same as for scrolls */
1005  op->value = (op->value*op->inv->value);
1006  op->level = op->inv->level/2+RANDOM()%difficulty+RANDOM()%difficulty;
1007  } else {
1008  FREE_AND_COPY(op->name, "potion");
1009  FREE_AND_COPY(op->name_pl, "potions");
1010  }
1011  if (!(flags&GT_ONLY_GOOD) && RANDOM()%2)
1013  break;
1014  }
1015 
1016  case AMULET:
1017  if (op->arch == amulet_arch)
1018  op->value *= 5; /* Since it's not just decoration */
1019  /* fall through */
1020  case RING:
1021  if (op->arch == NULL) {
1022  object_remove(op);
1024  op = NULL;
1025  break;
1026  }
1027  if (op->arch != ring_arch && op->arch != amulet_arch)
1028  /* It's a special artifact!*/
1029  break;
1030 
1031  if (GET_ANIM_ID(op))
1032  SET_ANIMATION(op, RANDOM()%((int)NUM_ANIMATIONS(op)));
1033  if (!(flags&GT_ONLY_GOOD) && !(RANDOM()%3))
1036  if (op->type != RING) /* Amulets have only one ability */
1037  break;
1038  if (!(RANDOM()%4)) {
1039  int d = (RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1040  if (d > 0)
1041  op->value *= 3;
1042  set_ring_bonus(op, d);
1043  if (!(RANDOM()%4)) {
1044  int d = (RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1045  if (d > 0)
1046  op->value *= 5;
1047  set_ring_bonus(op, d);
1048  }
1049  }
1050  break;
1051 
1052  case BOOK:
1053  /* Is it an empty book?, if yes lets make a special
1054  * msg for it, and tailor its properties based on the
1055  * creator and/or map level we found it on.
1056  */
1057  if (!op->msg && RANDOM()%10) {
1058  /* set the book level properly */
1059  if (creator->level == 0 || QUERY_FLAG(creator, FLAG_ALIVE)) {
1060  if (op->map && op->map->difficulty)
1061  op->level = RANDOM()%(op->map->difficulty)+RANDOM()%10+1;
1062  else
1063  op->level = RANDOM()%20+1;
1064  } else
1065  op->level = RANDOM()%creator->level;
1066 
1067  tailor_readable_ob(op, creator->stats.sp);
1068  /* books w/ info are worth more! */
1069  if (op->msg != NULL)
1070  op->value *= ((op->level > 10 ? op->level : (op->level+1)/2)*((strlen(op->msg)/250)+1));
1071  /* creator related stuff */
1072 
1073  if (creator->slaying && !op->slaying) /* for check_inv floors */
1074  op->slaying = add_string(creator->slaying);
1075 
1076  /* add exp so reading it gives xp (once)*/
1077  op->stats.exp = op->value > 10000 ? op->value/5 : op->value/10;
1078  }
1079  /* for library, chained books. Note that some monsters have
1080  * no_pick set - we don't want to set no pick in that case. */
1081  if (QUERY_FLAG(creator, FLAG_NO_PICK)
1082  && !QUERY_FLAG(creator, FLAG_MONSTER))
1084  break;
1085 
1086  case SPELLBOOK:
1087  op->value = op->value*op->inv->value;
1088  /* add exp so learning gives xp */
1089  op->level = op->inv->level;
1090  op->stats.exp = op->value;
1091  /* some more fun */
1092  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 5) {
1093  if (rndm(1, 6) <= 1)
1095  else
1097  } else if (rndm(1, 100) <= 1) {
1099  }
1100  break;
1101 
1102  case WAND:
1103  /* nrof in the treasure list is number of charges,
1104  * not number of wands. So copy that into food (charges),
1105  * and reset nrof.
1106  */
1107  op->stats.food = op->inv->nrof;
1108  op->nrof = 1;
1109  /* If the spell changes by level, choose a random level
1110  * for it, and adjust price. If the spell doesn't
1111  * change by level, just set the wand to the level of
1112  * the spell, and value calculation is simpler.
1113  */
1114  if (op->inv->duration_modifier
1115  || op->inv->dam_modifier
1116  || op->inv->range_modifier) {
1117  op->level = level_for_item(op, difficulty);
1118  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1119  } else {
1120  op->level = op->inv->level;
1121  op->value = op->value*op->inv->value;
1122  }
1123  break;
1124 
1125  case ROD:
1126  op->level = level_for_item(op, difficulty);
1127  rod_adjust(op);
1128  break;
1129 
1130  case SCROLL:
1131  op->level = level_for_item(op, difficulty);
1132  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1133  /* add exp so reading them properly gives xp */
1134  op->stats.exp = op->value/5;
1135  op->nrof = op->inv->nrof;
1136  /* some more fun */
1137  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 20) {
1138  if (rndm(1, 6) <= 1)
1140  else
1142  } else if (rndm(1, 100) <= 2) {
1144  }
1145  break;
1146 
1147  case RUNE:
1148  trap_adjust(op, difficulty);
1149  break;
1150 
1151  case TRAP:
1152  trap_adjust(op, difficulty);
1153  break;
1154  } /* switch type */
1155  }
1156  if (flags&GT_STARTEQUIP) {
1157  if (op->nrof < 2
1158  && op->type != CONTAINER
1159  && op->type != MONEY
1162  else if (op->type != MONEY)
1163  op->value = 0;
1164  }
1165 
1166  if (!(flags&GT_ENVIRONMENT))
1167  fix_flesh_item(op, creator);
1168 }
1169 
1173 static void dump_monster_treasure_rec(const char *name, treasure *t, int depth) {
1174  treasurelist *tl;
1175  int i;
1176 
1177  if (depth > 100)
1178  return;
1179 
1180  while (t != NULL) {
1181  if (t->name != NULL) {
1182  for (i = 0; i < depth; i++)
1183  fprintf(logfile, " ");
1184  fprintf(logfile, "{ (list: %s)\n", t->name);
1185  tl = find_treasurelist(t->name);
1186  dump_monster_treasure_rec(name, tl->items, depth+2);
1187  for (i = 0; i < depth; i++)
1188  fprintf(logfile, " ");
1189  fprintf(logfile, "} (end of list: %s)\n", t->name);
1190  } else {
1191  for (i = 0; i < depth; i++)
1192  fprintf(logfile, " ");
1193  if (t->item->clone.type == FLESH)
1194  fprintf(logfile, "%s's %s\n", name, t->item->clone.name);
1195  else
1196  fprintf(logfile, "%s\n", t->item->clone.name);
1197  }
1198  if (t->next_yes != NULL) {
1199  for (i = 0; i < depth; i++)
1200  fprintf(logfile, " ");
1201  fprintf(logfile, " (if yes)\n");
1202  dump_monster_treasure_rec(name, t->next_yes, depth+1);
1203  }
1204  if (t->next_no != NULL) {
1205  for (i = 0; i < depth; i++)
1206  fprintf(logfile, " ");
1207  fprintf(logfile, " (if no)\n");
1208  dump_monster_treasure_rec(name, t->next_no, depth+1);
1209  }
1210  t = t->next;
1211  }
1212 }
1213 
1218 void dump_monster_treasure(const char *name) {
1219  archetype *at;
1220  int found;
1221 
1222  found = 0;
1223  fprintf(logfile, "\n");
1224  for (at = get_next_archetype(NULL); at != NULL; at = get_next_archetype(at))
1225  if (!strcasecmp(at->clone.name, name) && at->clone.title == NULL) {
1226  fprintf(logfile, "treasures for %s (arch: %s)\n", at->clone.name, at->name);
1227  if (at->clone.randomitems != NULL)
1229  else
1230  fprintf(logfile, "(nothing)\n");
1231  fprintf(logfile, "\n");
1232  found++;
1233  }
1234 
1235  if (found == 0)
1236  fprintf(logfile, "No objects have the name %s!\n\n", name);
1237 }
1238 
1246 static void fix_flesh_item(object *item, const object *donor) {
1247  char tmpbuf[MAX_BUF];
1248  int i;
1249 
1250  if (item->type == FLESH && donor && QUERY_FLAG(donor, FLAG_MONSTER)) {
1251  /* change the name */
1252  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name);
1253  FREE_AND_COPY(item->name, tmpbuf);
1254  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name_pl);
1255  FREE_AND_COPY(item->name_pl, tmpbuf);
1256 
1257  /* store original arch in other_arch */
1258  if (!item->other_arch) {
1259  if (!donor->arch->reference_count) {
1260  item->other_arch = donor->arch;
1261  } else {
1262  /* If dealing with custom monsters, other_arch still needs to
1263  * point back to the original. Otherwise what happens
1264  * is that other_arch points at the custom archetype, but
1265  * that can be freed. Reference count doesn't work because
1266  * the loader will not be able to resolve the other_arch at
1267  * load time (server may has restarted, etc.)
1268  */
1269  archetype *original = find_archetype(donor->arch->name);
1270 
1271  if (original)
1272  item->other_arch = original;
1273  else {
1274  LOG(llevError, "could not find original archetype %s for custom monster!\n", donor->arch->name);
1275  abort();
1276  }
1277  }
1278  }
1279 
1280  /* weight is FLESH weight/100 * donor */
1281  if ((item->weight = (signed long)(((double)item->weight/(double)100.0)*(double)donor->weight)) == 0)
1282  item->weight = 1;
1283 
1284  /* value is multiplied by level of donor */
1285  item->value *= isqrt(donor->level*2);
1286 
1287  /* food value */
1288  item->stats.food += (donor->stats.hp/100)+donor->stats.Con;
1289 
1290  /* flesh items inherit some abilities of donor, but not full effect. */
1291  for (i = 0; i < NROFATTACKS; i++)
1292  item->resist[i] = donor->resist[i]/2;
1293 
1294  /* item inherits donor's level and exp (important for dragons) */
1295  item->level = donor->level;
1296  item->stats.exp = donor->stats.exp;
1297 
1298  /* if donor has some attacktypes, the flesh is poisonous */
1299  if (donor->attacktype&AT_POISON)
1300  item->type = POISON;
1301  if (donor->attacktype&AT_ACID)
1302  item->stats.hp = -1*item->stats.food;
1304 
1305  /* attempt to change the face - will take a face named "donor's arch"_"item's face". We ignore the animation for now */
1306  if (item->face != NULL) {
1307  snprintf(tmpbuf, sizeof(tmpbuf), "%s_%s", donor->arch->name, item->face->name);
1308  item->face = try_find_face(tmpbuf, item->face);
1309  }
1310  }
1311 }
1312 
1321 static int special_potion(object *op) {
1322  int i;
1323 
1324  if (op->attacktype)
1325  return 1;
1326 
1327  if (op->stats.Str
1328  || op->stats.Dex
1329  || op->stats.Con
1330  || op->stats.Pow
1331  || op->stats.Wis
1332  || op->stats.Int
1333  || op->stats.Cha)
1334  return 1;
1335 
1336  for (i = 0; i < NROFATTACKS; i++)
1337  if (op->resist[i])
1338  return 1;
1339 
1340  return 0;
1341 }
ATNR_PARALYZE
#define ATNR_PARALYZE
Definition: attack.h:61
global.h
fix_flesh_item
static void fix_flesh_item(object *item, const object *donor)
Definition: treasure.c:1246
liv::dam
int16_t dam
Definition: living.h:46
INS_NO_WALK_ON
#define INS_NO_WALK_ON
Definition: object.h:569
add_string
sstring add_string(const char *str)
Definition: shstr.c:124
object_remove
void object_remove(object *op)
Definition: object.c:1806
AT_POISON
#define AT_POISON
Definition: attack.h:86
BRACERS
@ BRACERS
Definition: object.h:217
llevError
@ llevError
Definition: logger.h:11
FABS
#define FABS(x)
Definition: define.h:22
WAND
@ WAND
Definition: object.h:220
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
Settings::armor_speed_linear
uint8_t armor_speed_linear
Definition: global.h:305
FLESH
@ FLESH
Definition: object.h:187
ATNR_ACID
#define ATNR_ACID
Definition: attack.h:55
level_for_item
static int level_for_item(const object *op, int difficulty)
Definition: treasure.c:302
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Definition: define.h:268
obj::map
struct mapdef * map
Definition: object.h:298
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
FLAG_REFL_MISSILE
#define FLAG_REFL_MISSILE
Definition: define.h:273
get_next_archetype
archetype * get_next_archetype(archetype *current)
Definition: assets.cpp:274
trap_adjust
static void trap_adjust(object *trap, int difficulty)
Definition: treasure.c:810
object_new
object * object_new(void)
Definition: object.c:1242
calc_item_power
int calc_item_power(const object *op)
Definition: item.c:238
FLAG_OBJ_ORIGINAL
#define FLAG_OBJ_ORIGINAL
Definition: define.h:357
TRAP
@ TRAP
Definition: object.h:241
ARMOUR
@ ARMOUR
Definition: object.h:120
set_materialname
void set_materialname(object *op)
Definition: utils.c:301
WEAPON
@ WEAPON
Definition: object.h:119
guildjoin.ob
ob
Definition: guildjoin.py:42
liv::hp
int16_t hp
Definition: living.h:40
GT_ONLY_GOOD
@ GT_ONLY_GOOD
Definition: treasure.h:34
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:160
ATNR_SLOW
#define ATNR_SLOW
Definition: attack.h:60
AMULET
@ AMULET
Definition: object.h:139
num_resist_table
#define num_resist_table
Definition: treasure.c:46
MAXMAGIC
#define MAXMAGIC
Definition: treasure.h:13
RUNE
@ RUNE
Definition: object.h:240
MAX_SPELLITEM_LEVEL
#define MAX_SPELLITEM_LEVEL
Definition: treasure.h:19
ATNR_DISEASE
#define ATNR_DISEASE
Definition: attack.h:74
find_treasurelist
treasurelist * find_treasurelist(const char *name)
Definition: assets.cpp:257
Ice.tmp
int tmp
Definition: Ice.py:207
FLAG_BLESSED
#define FLAG_BLESSED
Definition: define.h:369
rod_adjust
void rod_adjust(object *rod)
Definition: main.c:391
ATNR_PHYSICAL
#define ATNR_PHYSICAL
Definition: attack.h:49
ARMOUR_SPEED
#define ARMOUR_SPEED(xyz)
Definition: define.h:466
flags
static const flag_definition flags[]
Definition: gridarta-types-convert.c:101
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
create_all_treasures
static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:134
ATNR_TURN_UNDEAD
#define ATNR_TURN_UNDEAD
Definition: attack.h:62
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:242
amulet_arch
EXTERN archetype * amulet_arch
Definition: global.h:154
GT_STARTEQUIP
@ GT_STARTEQUIP
Definition: treasure.h:33
obj::randomitems
struct treasureliststruct * randomitems
Definition: object.h:389
treasurestruct
Definition: treasure.h:63
isqrt
int isqrt(int n)
Definition: utils.c:586
AT_DEATH
#define AT_DEATH
Definition: attack.h:93
FLAG_NO_PICK
#define FLAG_NO_PICK
Definition: define.h:239
ATNR_CONFUSION
#define ATNR_CONFUSION
Definition: attack.h:54
ATNR_HOLYWORD
#define ATNR_HOLYWORD
Definition: attack.h:70
archt
Definition: object.h:468
settings
struct Settings settings
Definition: init.c:39
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
obj::slaying
sstring slaying
Definition: object.h:320
free_string
void free_string(sstring str)
Definition: shstr.c:280
ATNR_BLIND
#define ATNR_BLIND
Definition: attack.h:71
CLOAK
@ CLOAK
Definition: object.h:204
liv::exp
int64_t exp
Definition: living.h:47
HELMET
@ HELMET
Definition: object.h:136
POISON
@ POISON
Definition: object.h:113
obj::name
sstring name
Definition: object.h:312
POTION
@ POTION
Definition: object.h:111
GT_INVISIBLE
@ GT_INVISIBLE
Definition: treasure.h:32
resist_table
static int resist_table[]
Definition: treasure.c:37
special_potion
static int special_potion(object *op)
Definition: treasure.c:1321
liv::Cha
int8_t Cha
Definition: living.h:36
ROD
@ ROD
Definition: object.h:109
CONTAINER
@ CONTAINER
Definition: object.h:231
get_magic
static int get_magic(int diff)
Definition: treasure.c:789
difftomagic_list
static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1]
Definition: treasure.c:338
generate_artifact
void generate_artifact(object *op, int difficulty)
Definition: artifact.c:143
change_treasure
static void change_treasure(treasure *t, object *op)
Definition: treasure.c:98
Settings::armor_weight_reduction
int armor_weight_reduction
Definition: global.h:302
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Definition: global.h:202
Ice.b
b
Definition: Ice.py:48
crown_arch
EXTERN archetype * crown_arch
Definition: global.h:154
obj::x
int16_t x
Definition: object.h:328
INS_NO_MERGE
#define INS_NO_MERGE
Definition: object.h:567
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
ATNR_DRAIN
#define ATNR_DRAIN
Definition: attack.h:56
obj::other_arch
struct archt * other_arch
Definition: object.h:417
rndm
int rndm(int min, int max)
Definition: utils.c:162
liv::Con
int8_t Con
Definition: living.h:36
ATNR_POISON
#define ATNR_POISON
Definition: attack.h:59
sproto.h
ATNR_DEATH
#define ATNR_DEATH
Definition: attack.h:66
FLAG_NO_STEAL
#define FLAG_NO_STEAL
Definition: define.h:342
set_magic
static void set_magic(int difficulty, object *op, int max_magic, int flags)
Definition: treasure.c:639
GET_ANIM_ID
#define GET_ANIM_ID(ob)
Definition: global.h:163
BOOK
@ BOOK
Definition: object.h:114
GT_ENVIRONMENT
@ GT_ENVIRONMENT
Definition: treasure.h:31
logfile
EXTERN FILE * logfile
Definition: global.h:136
RING
@ RING
Definition: object.h:185
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
treasure.h
MAX_BUF
#define MAX_BUF
Definition: define.h:35
fix_generated_item
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.c:877
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:281
RANDOM
#define RANDOM()
Definition: define.h:642
ATNR_FIRE
#define ATNR_FIRE
Definition: attack.h:51
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
obj::y
int16_t y
Definition: object.h:328
put_treasure
static void put_treasure(object *op, object *creator, int flags)
Definition: treasure.c:75
treasureliststruct::total_chance
int16_t total_chance
Definition: treasure.h:84
obj::title
sstring title
Definition: object.h:318
obj::arch
struct archt * arch
Definition: object.h:416
treasureliststruct::items
struct treasurestruct * items
Definition: treasure.h:89
tailor_readable_ob
void tailor_readable_ob(object *book, int msg_type)
Definition: readable.c:1924
FLAG_REFL_SPELL
#define FLAG_REFL_SPELL
Definition: define.h:275
obj::type
uint8_t type
Definition: object.h:341
Floor.t
t
Definition: Floor.py:62
obj::stats
living stats
Definition: object.h:371
archt::clone
object clone
Definition: object.h:472
obj::weight
int32_t weight
Definition: object.h:368
ATNR_DEPLETE
#define ATNR_DEPLETE
Definition: attack.h:65
item
Definition: item.py:1
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
archt::reference_count
int reference_count
Definition: object.h:475
give.op
op
Definition: give.py:33
autojail.value
value
Definition: autojail.py:6
get_power_from_ench
int get_power_from_ench(int ench)
Definition: item.c:210
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:278
dump_monster_treasure
void dump_monster_treasure(const char *name)
Definition: treasure.c:1218
ATNR_MAGIC
#define ATNR_MAGIC
Definition: attack.h:50
magic_from_difficulty
static int magic_from_difficulty(int difficulty)
Definition: treasure.c:551
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.c:219
CHANCE_FOR_ARTIFACT
#define CHANCE_FOR_ARTIFACT
Definition: treasure.h:10
NUM_ANIMATIONS
#define NUM_ANIMATIONS(ob)
Definition: global.h:169
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2820
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
DIFFLEVELS
#define DIFFLEVELS
Definition: treasure.h:16
Settings::armor_weight_linear
uint8_t armor_weight_linear
Definition: global.h:303
strcasecmp
int strcasecmp(const char *s1, const char *s2)
make_face_from_files.int
int
Definition: make_face_from_files.py:26
DICE2
#define DICE2
Definition: treasure.c:848
AT_ACID
#define AT_ACID
Definition: attack.h:82
loader.h
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:2067
get_attr_value
int8_t get_attr_value(const living *stats, int attr)
Definition: living.c:314
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1533
try_find_face
const Face * try_find_face(const char *name, const Face *error)
Definition: assets.cpp:306
level
int level
Definition: readable.c:1604
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:274
archt::name
sstring name
Definition: object.h:469
ATNR_GHOSTHIT
#define ATNR_GHOSTHIT
Definition: attack.h:58
set_abs_magic
void set_abs_magic(object *op, int magic)
Definition: treasure.c:591
ATNR_COLD
#define ATNR_COLD
Definition: attack.h:53
SCROLL
@ SCROLL
Definition: object.h:221
create_one_treasure
static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:178
obj::attacktype
uint32_t attacktype
Definition: object.h:345
ATNR_ELECTRICITY
#define ATNR_ELECTRICITY
Definition: attack.h:52
SPELL
@ SPELL
Definition: object.h:214
ring_arch
EXTERN archetype * ring_arch
Definition: global.h:154
liv::sp
int16_t sp
Definition: living.h:42
SHIELD
@ SHIELD
Definition: object.h:135
init_archetype_pointers
void init_archetype_pointers(void)
Definition: treasure.c:55
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
spell_mapping
const char *const spell_mapping[SPELL_MAPPINGS]
Definition: object.c:63
ATNR_LIFE_STEALING
#define ATNR_LIFE_STEALING
Definition: attack.h:73
obj::resist
int16_t resist[NROFATTACKS]
Definition: object.h:344
FLAG_IS_THROWN
#define FLAG_IS_THROWN
Definition: define.h:249
if
if(!(yy_init))
Definition: loader.c:2589
set_ring_bonus
static void set_ring_bonus(object *op, int bonus)
Definition: treasure.c:668
Settings::armor_speed_improvement
int armor_speed_improvement
Definition: global.h:304
SPELLBOOK
@ SPELLBOOK
Definition: object.h:203
GT_MINIMAL
@ GT_MINIMAL
Definition: treasure.h:36
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
dump_monster_treasure_rec
static void dump_monster_treasure_rec(const char *name, treasure *t, int depth)
Definition: treasure.c:1173
obj::level
int16_t level
Definition: object.h:354
llevDebug
@ llevDebug
Definition: logger.h:13
MONEY
@ MONEY
Definition: object.h:137
treasureliststruct
Definition: treasure.h:82
obj::inv
struct obj * inv
Definition: object.h:291
give.name
name
Definition: give.py:27
ATNR_FEAR
#define ATNR_FEAR
Definition: attack.h:63
level
Definition: level.py:1