Crossfire Server, Trunk
treasure.cpp
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 #include "assets.h"
31 #include "AssetsManager.h"
32 
39 static int resist_table[] = {
45 };
46 
50 static archetype *ring_arch = NULL, *amulet_arch = NULL, *crown_arch = NULL;
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 
63  if (ring_arch == NULL)
64  ring_arch = find_archetype("ring");
65  if (amulet_arch == NULL)
66  amulet_arch = find_archetype("amulet");
67  if (crown_arch == NULL)
68  crown_arch = find_archetype("crown");
69 }
70 
82 static void put_treasure(object *op, object *creator, int flags) {
83  /* Bit of a hack - spells should never be put onto the map. The entire
84  * treasure stuff is a problem - there is no clear idea of knowing
85  * this is the original object, or if this is an object that should be created
86  * by another object.
87  */
88  if (flags&GT_ENVIRONMENT && op->type != SPELL) {
90  object_insert_in_map_at(op, creator->map, op, INS_NO_MERGE|INS_NO_WALK_ON, creator->x, creator->y);
91  } else
92  object_insert_in_ob(op, creator);
93 }
94 
105 static void change_treasure(treasure *t, object *op) {
106  /* CMD: change_name xxxx */
107  if (t->change_arch.name) {
108  FREE_AND_COPY(op->name, t->change_arch.name);
109  /* not great, but better than something that is completely wrong */
110  FREE_AND_COPY(op->name_pl, t->change_arch.name);
111  }
112 
113  if (t->change_arch.title) {
114  if (op->title)
115  free_string(op->title);
116  op->title = add_string(t->change_arch.title);
117  }
118 
119  if (t->change_arch.slaying) {
120  if (op->slaying)
121  free_string(op->slaying);
122  op->slaying = add_string(t->change_arch.slaying);
123  }
124 }
125 
139 static void do_single_item(treasure *t, object *op, int flag, int difficulty) {
140  if (t->item && (t->item->clone.invisible != 0 || !(flag&GT_INVISIBLE))) {
141  object *tmp = arch_to_object(t->item);
142  if (t->nrof && tmp->nrof <= 1)
143  tmp->nrof = RANDOM()%((int)t->nrof)+1;
144  if (t->artifact) {
145  const artifact *art = find_artifact(tmp, t->artifact);
146  if (!art || !legal_artifact_combination(tmp, art)) {
147  LOG(llevError, "Invalid artifact %s for treasure %s\n", t->artifact, tmp->arch->name);
149  return;
150  }
152  } else {
153  fix_generated_item(tmp, op, difficulty, t->magic, flag);
155  }
156  put_treasure(tmp, op, flag);
157  }
158 }
159 
175 static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries) {
176  if ((int)t->chance >= 100 || (RANDOM()%100+1) < t->chance) {
177  if (t->name) {
178  if (strcmp(t->name, "NONE") && difficulty >= t->magic)
179  create_treasure(find_treasurelist(t->name), op, flag, t->list_magic_value ? t->list_magic_value : difficulty + t->list_magic_adjustment, tries);
180  } else {
181  do_single_item(t, op, flag, difficulty);
182  }
183  if (t->next_yes != NULL)
184  create_all_treasures(t->next_yes, op, flag, difficulty, tries);
185  } else
186  if (t->next_no != NULL)
187  create_all_treasures(t->next_no, op, flag, difficulty, tries);
188  if (t->next != NULL)
189  create_all_treasures(t->next, op, flag, difficulty, tries);
190 }
191 
210 static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries) {
211  int value = RANDOM()%tl->total_chance;
212  treasure *t;
213 
214  if (tries++ > 100) {
215  LOG(llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
216  return;
217  }
218 
219  for (t = tl->items; t != NULL; t = t->next) {
220  value -= t->chance;
221  if (value < 0)
222  break;
223  }
224 
225  if (!t || value >= 0) {
226  LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n");
227  abort();
228  }
229  if (t->name) {
230  if (!strcmp(t->name, "NONE"))
231  return;
232  if (difficulty >= t->magic)
233  create_treasure(find_treasurelist(t->name), op, flag, t->list_magic_value ? t->list_magic_value : difficulty + t->list_magic_adjustment, tries);
234  else if (t->nrof)
235  create_one_treasure(tl, op, flag, difficulty, tries);
236  return;
237  }
238  if ((t->item) && (flag&GT_ONLY_GOOD)) { /* Generate only good items, damnit !*/
239  if (QUERY_FLAG(&(t->item->clone), FLAG_CURSED)
240  || QUERY_FLAG(&(t->item->clone), FLAG_DAMNED)) {
241  create_one_treasure(tl, op, flag, difficulty, tries+1);
242  return;
243  }
244  }
245  do_single_item(t, op, flag, difficulty);
246 }
247 
263 void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries) {
264  if (tries++ > 100) {
265  LOG(llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
266  return;
267  }
268  if (!t->items) {
269  LOG(llevError, "Empty treasure list %s\n", t->name);
270  return;
271  }
272  if (t->total_chance)
273  create_one_treasure(t, op, flag, difficulty, tries);
274  else
275  create_all_treasures(t->items, op, flag, difficulty, tries);
276 }
277 
295 object *generate_treasure(treasurelist *t, int difficulty) {
296  object *ob = object_new(), *tmp;
297 
298  create_treasure(t, ob, 0, difficulty, 0);
299 
300  /* Don't want to free the object we are about to return */
301  tmp = ob->inv;
302  if (tmp != NULL)
304  if (ob->inv) {
305  LOG(llevError, "In generate treasure, created multiple objects.\n");
306  }
308  return tmp;
309 }
310 
323 static int level_for_item(const object *op, int difficulty) {
324  int level, mult, olevel;
325 
326  if (!op->inv) {
327  LOG(llevError, "level_for_item: Object %s has no inventory!\n", op->name);
328  return 0;
329  }
330  level = op->inv->level;
331 
332  /* Basically, we set mult to the lowest spell increase attribute that is
333  * not zero - zero's mean no modification is done, so we don't want those.
334  * given we want non zero results, we can't just use a few MIN's here.
335  */
336  mult = op->inv->dam_modifier;
337  if (op->inv->range_modifier && (op->inv->range_modifier < mult || mult == 0))
338  mult = op->inv->range_modifier;
339  if (op->inv->duration_modifier && (op->inv->duration_modifier < mult || mult == 0))
340  mult = op->inv->duration_modifier;
341 
342  if (mult == 0)
343  mult = 5;
344 
345  // This should give us roughly a normal distribution averaged at difficulty.
346  olevel = rndm(0, difficulty)+rndm(0, difficulty);
347  // Now we truncate to the closest level + n * mult value below.
348  olevel = ((olevel-level)/mult)*mult+level; // This should truncate to a multiple of mult for us.
349  if (olevel > MAX_SPELLITEM_LEVEL)
350  olevel = MAX_SPELLITEM_LEVEL;
351  // Make sure we hit the minimum spell level, too
352  else if (olevel < level)
353  olevel = level;
354 
355  return olevel;
356 }
357 
365 static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1] = {
366 /*chance of magic difficulty*/
367 /* +0 +1 +2 +3 +4 */
368  { 94, 3, 2, 1, 0 }, /*1*/
369  { 94, 3, 2, 1, 0 }, /*2*/
370  { 94, 3, 2, 1, 0 }, /*3*/
371  { 94, 3, 2, 1, 0 }, /*4*/
372  { 94, 3, 2, 1, 0 }, /*5*/
373  { 90, 4, 3, 2, 1 }, /*6*/
374  { 90, 4, 3, 2, 1 }, /*7*/
375  { 90, 4, 3, 2, 1 }, /*8*/
376  { 90, 4, 3, 2, 1 }, /*9*/
377  { 90, 4, 3, 2, 1 }, /*10*/
378  { 85, 6, 4, 3, 2 }, /*11*/
379  { 85, 6, 4, 3, 2 }, /*12*/
380  { 85, 6, 4, 3, 2 }, /*13*/
381  { 85, 6, 4, 3, 2 }, /*14*/
382  { 85, 6, 4, 3, 2 }, /*15*/
383  { 81, 8, 5, 4, 3 }, /*16*/
384  { 81, 8, 5, 4, 3 }, /*17*/
385  { 81, 8, 5, 4, 3 }, /*18*/
386  { 81, 8, 5, 4, 3 }, /*19*/
387  { 81, 8, 5, 4, 3 }, /*20*/
388  { 75, 10, 6, 5, 4 }, /*21*/
389  { 75, 10, 6, 5, 4 }, /*22*/
390  { 75, 10, 6, 5, 4 }, /*23*/
391  { 75, 10, 6, 5, 4 }, /*24*/
392  { 75, 10, 6, 5, 4 }, /*25*/
393  { 70, 12, 7, 6, 5 }, /*26*/
394  { 70, 12, 7, 6, 5 }, /*27*/
395  { 70, 12, 7, 6, 5 }, /*28*/
396  { 70, 12, 7, 6, 5 }, /*29*/
397  { 70, 12, 7, 6, 5 }, /*30*/
398  { 70, 9, 8, 7, 6 }, /*31*/
399  { 70, 9, 8, 7, 6 }, /*32*/
400  { 70, 9, 8, 7, 6 }, /*33*/
401  { 70, 9, 8, 7, 6 }, /*34*/
402  { 70, 9, 8, 7, 6 }, /*35*/
403  { 70, 6, 9, 8, 7 }, /*36*/
404  { 70, 6, 9, 8, 7 }, /*37*/
405  { 70, 6, 9, 8, 7 }, /*38*/
406  { 70, 6, 9, 8, 7 }, /*39*/
407  { 70, 6, 9, 8, 7 }, /*40*/
408  { 70, 3, 10, 9, 8 }, /*41*/
409  { 70, 3, 10, 9, 8 }, /*42*/
410  { 70, 3, 10, 9, 8 }, /*43*/
411  { 70, 3, 10, 9, 8 }, /*44*/
412  { 70, 3, 10, 9, 8 }, /*45*/
413  { 70, 2, 9, 10, 9 }, /*46*/
414  { 70, 2, 9, 10, 9 }, /*47*/
415  { 70, 2, 9, 10, 9 }, /*48*/
416  { 70, 2, 9, 10, 9 }, /*49*/
417  { 70, 2, 9, 10, 9 }, /*50*/
418  { 70, 2, 7, 11, 10 }, /*51*/
419  { 70, 2, 7, 11, 10 }, /*52*/
420  { 70, 2, 7, 11, 10 }, /*53*/
421  { 70, 2, 7, 11, 10 }, /*54*/
422  { 70, 2, 7, 11, 10 }, /*55*/
423  { 70, 2, 5, 12, 11 }, /*56*/
424  { 70, 2, 5, 12, 11 }, /*57*/
425  { 70, 2, 5, 12, 11 }, /*58*/
426  { 70, 2, 5, 12, 11 }, /*59*/
427  { 70, 2, 5, 12, 11 }, /*60*/
428  { 70, 2, 3, 13, 12 }, /*61*/
429  { 70, 2, 3, 13, 12 }, /*62*/
430  { 70, 2, 3, 13, 12 }, /*63*/
431  { 70, 2, 3, 13, 12 }, /*64*/
432  { 70, 2, 3, 13, 12 }, /*65*/
433  { 70, 2, 3, 12, 13 }, /*66*/
434  { 70, 2, 3, 12, 13 }, /*67*/
435  { 70, 2, 3, 12, 13 }, /*68*/
436  { 70, 2, 3, 12, 13 }, /*69*/
437  { 70, 2, 3, 12, 13 }, /*70*/
438  { 70, 2, 3, 11, 14 }, /*71*/
439  { 70, 2, 3, 11, 14 }, /*72*/
440  { 70, 2, 3, 11, 14 }, /*73*/
441  { 70, 2, 3, 11, 14 }, /*74*/
442  { 70, 2, 3, 11, 14 }, /*75*/
443  { 70, 2, 3, 10, 15 }, /*76*/
444  { 70, 2, 3, 10, 15 }, /*77*/
445  { 70, 2, 3, 10, 15 }, /*78*/
446  { 70, 2, 3, 10, 15 }, /*79*/
447  { 70, 2, 3, 10, 15 }, /*80*/
448  { 70, 2, 3, 9, 16 }, /*81*/
449  { 70, 2, 3, 9, 16 }, /*82*/
450  { 70, 2, 3, 9, 16 }, /*83*/
451  { 70, 2, 3, 9, 16 }, /*84*/
452  { 70, 2, 3, 9, 16 }, /*85*/
453  { 70, 2, 3, 8, 17 }, /*86*/
454  { 70, 2, 3, 8, 17 }, /*87*/
455  { 70, 2, 3, 8, 17 }, /*88*/
456  { 70, 2, 3, 8, 17 }, /*89*/
457  { 70, 2, 3, 8, 17 }, /*90*/
458  { 70, 2, 3, 7, 18 }, /*91*/
459  { 70, 2, 3, 7, 18 }, /*92*/
460  { 70, 2, 3, 7, 18 }, /*93*/
461  { 70, 2, 3, 7, 18 }, /*94*/
462  { 70, 2, 3, 7, 18 }, /*95*/
463  { 70, 2, 3, 6, 19 }, /*96*/
464  { 70, 2, 3, 6, 19 }, /*97*/
465  { 70, 2, 3, 6, 19 }, /*98*/
466  { 70, 2, 3, 6, 19 }, /*99*/
467  { 70, 2, 3, 6, 19 }, /*100*/
468  { 70, 2, 3, 6, 19 }, /*101*/
469  { 70, 2, 3, 6, 19 }, /*101*/
470  { 70, 2, 3, 6, 19 }, /*102*/
471  { 70, 2, 3, 6, 19 }, /*103*/
472  { 70, 2, 3, 6, 19 }, /*104*/
473  { 70, 2, 3, 6, 19 }, /*105*/
474  { 70, 2, 3, 6, 19 }, /*106*/
475  { 70, 2, 3, 6, 19 }, /*107*/
476  { 70, 2, 3, 6, 19 }, /*108*/
477  { 70, 2, 3, 6, 19 }, /*109*/
478  { 70, 2, 3, 6, 19 }, /*110*/
479  { 70, 2, 3, 6, 19 }, /*111*/
480  { 70, 2, 3, 6, 19 }, /*112*/
481  { 70, 2, 3, 6, 19 }, /*113*/
482  { 70, 2, 3, 6, 19 }, /*114*/
483  { 70, 2, 3, 6, 19 }, /*115*/
484  { 70, 2, 3, 6, 19 }, /*116*/
485  { 70, 2, 3, 6, 19 }, /*117*/
486  { 70, 2, 3, 6, 19 }, /*118*/
487  { 70, 2, 3, 6, 19 }, /*119*/
488  { 70, 2, 3, 6, 19 }, /*120*/
489  { 70, 2, 3, 6, 19 }, /*121*/
490  { 70, 2, 3, 6, 19 }, /*122*/
491  { 70, 2, 3, 6, 19 }, /*123*/
492  { 70, 2, 3, 6, 19 }, /*124*/
493  { 70, 2, 3, 6, 19 }, /*125*/
494  { 70, 2, 3, 6, 19 }, /*126*/
495  { 70, 2, 3, 6, 19 }, /*127*/
496  { 70, 2, 3, 6, 19 }, /*128*/
497  { 70, 2, 3, 6, 19 }, /*129*/
498  { 70, 2, 3, 6, 19 }, /*130*/
499  { 70, 2, 3, 6, 19 }, /*131*/
500  { 70, 2, 3, 6, 19 }, /*132*/
501  { 70, 2, 3, 6, 19 }, /*133*/
502  { 70, 2, 3, 6, 19 }, /*134*/
503  { 70, 2, 3, 6, 19 }, /*135*/
504  { 70, 2, 3, 6, 19 }, /*136*/
505  { 70, 2, 3, 6, 19 }, /*137*/
506  { 70, 2, 3, 6, 19 }, /*138*/
507  { 70, 2, 3, 6, 19 }, /*139*/
508  { 70, 2, 3, 6, 19 }, /*140*/
509  { 70, 2, 3, 6, 19 }, /*141*/
510  { 70, 2, 3, 6, 19 }, /*142*/
511  { 70, 2, 3, 6, 19 }, /*143*/
512  { 70, 2, 3, 6, 19 }, /*144*/
513  { 70, 2, 3, 6, 19 }, /*145*/
514  { 70, 2, 3, 6, 19 }, /*146*/
515  { 70, 2, 3, 6, 19 }, /*147*/
516  { 70, 2, 3, 6, 19 }, /*148*/
517  { 70, 2, 3, 6, 19 }, /*149*/
518  { 70, 2, 3, 6, 19 }, /*150*/
519  { 70, 2, 3, 6, 19 }, /*151*/
520  { 70, 2, 3, 6, 19 }, /*152*/
521  { 70, 2, 3, 6, 19 }, /*153*/
522  { 70, 2, 3, 6, 19 }, /*154*/
523  { 70, 2, 3, 6, 19 }, /*155*/
524  { 70, 2, 3, 6, 19 }, /*156*/
525  { 70, 2, 3, 6, 19 }, /*157*/
526  { 70, 2, 3, 6, 19 }, /*158*/
527  { 70, 2, 3, 6, 19 }, /*159*/
528  { 70, 2, 3, 6, 19 }, /*160*/
529  { 70, 2, 3, 6, 19 }, /*161*/
530  { 70, 2, 3, 6, 19 }, /*162*/
531  { 70, 2, 3, 6, 19 }, /*163*/
532  { 70, 2, 3, 6, 19 }, /*164*/
533  { 70, 2, 3, 6, 19 }, /*165*/
534  { 70, 2, 3, 6, 19 }, /*166*/
535  { 70, 2, 3, 6, 19 }, /*167*/
536  { 70, 2, 3, 6, 19 }, /*168*/
537  { 70, 2, 3, 6, 19 }, /*169*/
538  { 70, 2, 3, 6, 19 }, /*170*/
539  { 70, 2, 3, 6, 19 }, /*171*/
540  { 70, 2, 3, 6, 19 }, /*172*/
541  { 70, 2, 3, 6, 19 }, /*173*/
542  { 70, 2, 3, 6, 19 }, /*174*/
543  { 70, 2, 3, 6, 19 }, /*175*/
544  { 70, 2, 3, 6, 19 }, /*176*/
545  { 70, 2, 3, 6, 19 }, /*177*/
546  { 70, 2, 3, 6, 19 }, /*178*/
547  { 70, 2, 3, 6, 19 }, /*179*/
548  { 70, 2, 3, 6, 19 }, /*180*/
549  { 70, 2, 3, 6, 19 }, /*181*/
550  { 70, 2, 3, 6, 19 }, /*182*/
551  { 70, 2, 3, 6, 19 }, /*183*/
552  { 70, 2, 3, 6, 19 }, /*184*/
553  { 70, 2, 3, 6, 19 }, /*185*/
554  { 70, 2, 3, 6, 19 }, /*186*/
555  { 70, 2, 3, 6, 19 }, /*187*/
556  { 70, 2, 3, 6, 19 }, /*188*/
557  { 70, 2, 3, 6, 19 }, /*189*/
558  { 70, 2, 3, 6, 19 }, /*190*/
559  { 70, 2, 3, 6, 19 }, /*191*/
560  { 70, 2, 3, 6, 19 }, /*192*/
561  { 70, 2, 3, 6, 19 }, /*193*/
562  { 70, 2, 3, 6, 19 }, /*194*/
563  { 70, 2, 3, 6, 19 }, /*195*/
564  { 70, 2, 3, 6, 19 }, /*196*/
565  { 70, 2, 3, 6, 19 }, /*197*/
566  { 70, 2, 3, 6, 19 }, /*198*/
567  { 70, 2, 3, 6, 19 }, /*199*/
568  { 70, 2, 3, 6, 19 }, /*200*/
569 };
570 
578 static int magic_from_difficulty(int difficulty) {
579  int percent, loop;
580 
581  difficulty--;
582  if (difficulty < 0)
583  difficulty = 0;
584 
585  if (difficulty >= DIFFLEVELS)
586  difficulty = DIFFLEVELS-1;
587 
588  percent = RANDOM()%100;
589 
590  for (loop = 0; loop < (MAXMAGIC+1); ++loop) {
591  percent -= difftomagic_list[difficulty][loop];
592  if (percent < 0)
593  break;
594  }
595  if (loop == (MAXMAGIC+1)) {
596  LOG(llevError, "Warning, table for difficulty %d bad.\n", difficulty);
597  loop = 0;
598  }
599  /* LOG(llevDebug, "Chose magic %d for difficulty %d\n", loop, difficulty);*/
600  return (RANDOM()%3) ? loop : -loop;
601 }
602 
618 void set_abs_magic(object *op, int magic) {
619  int32_t base_weight, base_speed;
620  if (!magic)
621  return;
622 
623  op->magic = magic;
624  if (op->arch) {
625  base_weight = op->arch->clone.weight;
626  base_speed = ARMOUR_SPEED(&op->arch->clone);
627  }
628  else {
629  base_weight = op->weight;
630  base_speed = ARMOUR_SPEED(op);
631  }
632  // Now we do the calculations
633  if (op->type == ARMOUR) {
635  ARMOUR_SPEED(op) = base_speed*(100+magic*settings.armor_speed_improvement)/100;
636  else
637  // This could have been done with a loop, but that seems to be less scalable.
638  // This will introduce less roundoff error than a loop, anyway
639  ARMOUR_SPEED(op) = (int32_t)(base_speed * pow(((float)(100+settings.armor_speed_improvement))/100, magic));
640  }
641  // Prepare for handling the weight. Sometimes cursed ones will have low weight like good ones.
642  if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */
643  magic = (-magic);
645  op->weight = (base_weight*(100-magic*settings.armor_weight_reduction))/100;
646  else
647  op->weight = (int32_t)(base_weight * pow(((float)(100-settings.armor_weight_reduction))/100, magic));
648 
649 }
650 
666 static void set_magic(int difficulty, object *op, int max_magic, int flags) {
667  int i;
668 
669  i = magic_from_difficulty(difficulty);
670  if ((flags&GT_ONLY_GOOD) && i < 0)
671  i = -i;
672  if (i > max_magic)
673  i = max_magic;
674  set_abs_magic(op, i);
675  if (i < 0)
677 }
678 
695 static void set_ring_bonus(object *op, int bonus) {
696  int r = RANDOM()%(bonus > 0 ? 25 : 11);
697 
698  if (op->type == AMULET) {
699  if (!(RANDOM()%21))
700  r = 20+RANDOM()%2;
701  else {
702  if (RANDOM()&2)
703  r = 10;
704  else
705  r = 11+RANDOM()%9;
706  }
707  }
708 
709  switch (r) {
710  /* Redone by MSW 2000-11-26 to have much less code. Also,
711  * bonuses and penalties will stack and add to existing values.
712  * of the item.
713  */
714  case 0:
715  case 1:
716  case 2:
717  case 3:
718  case 4:
719  case 5:
720  case 6:
721  set_attr_value(&op->stats, r, (signed char)(bonus+get_attr_value(&op->stats, r)));
722  break;
723 
724  case 7:
725  op->stats.dam += bonus;
726  break;
727 
728  case 8:
729  op->stats.wc += bonus;
730  break;
731 
732  case 9:
733  op->stats.food += bonus; /* hunger/sustenance */
734  break;
735 
736  case 10:
737  op->stats.ac += bonus;
738  break;
739 
740  /* Item that gives protections/vulnerabilities */
741  case 11:
742  case 12:
743  case 13:
744  case 14:
745  case 15:
746  case 16:
747  case 17:
748  case 18:
749  case 19: {
750  int b = 5+FABS(bonus), val, resist = RANDOM()%num_resist_table;
751 
752  /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
753  val = 10+RANDOM()%b+RANDOM()%b+RANDOM()%b+RANDOM()%b;
754 
755  /* Cursed items need to have higher negative values to equal out with
756  * positive values for how protections work out. Put another
757  * little random element in since that they don't always end up with
758  * even values.
759  */
760  if (bonus < 0)
761  val = 2*-val-RANDOM()%b;
762  if (val > 35)
763  val = 35; /* Upper limit */
764  b = 0;
765  while (op->resist[resist_table[resist]] != 0 && b++ < 4) {
766  resist = RANDOM()%num_resist_table;
767  }
768  if (b == 4)
769  return; /* Not able to find a free resistance */
770  op->resist[resist_table[resist]] = val;
771  /* We should probably do something more clever here to adjust value
772  * based on how good a resistance we gave.
773  */
774  break;
775  }
776 
777  case 20:
778  if (op->type == AMULET) {
780  op->value *= 11;
781  } else {
782  op->stats.hp = 1; /* regenerate hit points */
783  op->value *= 4;
784  }
785  break;
786 
787  case 21:
788  if (op->type == AMULET) {
790  op->value *= 9;
791  } else {
792  op->stats.sp = 1; /* regenerate spell points */
793  op->value *= 3;
794  }
795  break;
796 
797  case 22:
798  op->stats.grace += bonus; /* regenerate grace */
799  op->value *= 5;
800  break;
801 
802  case 23:
803  op->stats.exp += bonus; /* Speed! */
804  op->value = (op->value*2)/3;
805  break;
806  }
807  if (bonus > 0)
808  op->value *= 2*bonus;
809  else
810  op->value = -(op->value*2*bonus)/3;
811 }
812 
821 static int get_magic(int diff) {
822  int i;
823 
824  if (diff < 3)
825  diff = 3;
826  for (i = 0; i < 4; i++)
827  if (RANDOM()%diff)
828  return i;
829  return 4;
830 }
831 
842 static void trap_adjust(object *trap, int difficulty) {
843  int i;
844 
845  /* now we set the trap level to match the difficulty of the level
846  * the formula below will give a level from 1 to (2*difficulty) with
847  * a peak probability at difficulty
848  */
849 
850  trap->level = rndm(0, difficulty-1)+rndm(0, difficulty-1);
851  if (trap->level < 1)
852  trap->level = 1;
853 
854  /* set the hiddenness of the trap, similar formula to above */
855  trap->stats.Cha = rndm(0, 19)+rndm(0, difficulty-1)+rndm(0, difficulty-1);
856 
857  if (!trap->other_arch && !trap->inv) {
858  /* set the damage of the trap.
859  * we get 0-4 pts of damage per level of difficulty of the map in
860  * the trap
861  */
862 
863  trap->stats.dam = 0;
864  for (i = 0; i < difficulty; i++)
865  trap->stats.dam += rndm(0, 4);
866 
867  /* the poison trap special case */
868  if (trap->attacktype&AT_POISON) {
869  trap->stats.dam = rndm(0, difficulty-1);
870  if (trap->stats.dam < 1)
871  trap->stats.dam = 1;
872  }
873 
874  /* so we get an appropriate amnt of exp for AT_DEATH traps */
875  if (trap->attacktype&AT_DEATH)
876  trap->stats.dam = 127;
877  }
878 }
879 
880 #define DICE2 (get_magic(2) == 2 ? 2 : 1)
881 #define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3)
882 
909 void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags) {
910  int was_magic = op->magic, num_enchantments = 0, save_item_power;
911 
912  if (!creator || creator->type == op->type)
913  creator = op; /* safety & to prevent polymorphed objects giving attributes */
914 
915  /* If we make an artifact, this information will be destroyed */
916  save_item_power = op->item_power;
917  op->item_power = 0;
918 
919  if (op->randomitems && op->type != SPELL) {
920  create_treasure(op->randomitems, op, flags, difficulty, 0);
921  if (!op->inv)
922  LOG(llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->name);
923  /* So the treasure doesn't get created again */
924  op->randomitems = NULL;
925  }
926 
927  if (difficulty < 1)
928  difficulty = 1;
929  if (!(flags&GT_MINIMAL)) {
930  if (op->arch == crown_arch) {
931  set_magic(difficulty > 25 ? 30 : difficulty+5, op, max_magic, flags);
932  num_enchantments = calc_item_power(op);
933  generate_artifact(op, difficulty);
934  } else {
935  if (!op->magic && max_magic)
936  set_magic(difficulty, op, max_magic, flags);
937  num_enchantments = calc_item_power(op);
938  if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT))
939  || op->type == ROD
940  || difficulty >= 999)
941  generate_artifact(op, difficulty);
942  }
943 
944  /* Object was made an artifact. Calculate its item_power rating.
945  * the item_power in the object is what the artifact adds.
946  */
947  if (op->title) {
948  /* if save_item_power is set, then most likely we started with an
949  * artifact and have added new abilities to it - this is rare, but
950  * but I have seen things like 'strange rings of fire'. So just
951  * figure out the power from the base power plus what this one adds.
952  * Note that since item_power is not quite linear, this actually
953  * ends up being somewhat of a bonus.
954  */
955  if (save_item_power)
956  op->item_power = save_item_power+get_power_from_ench(op->item_power);
957  else
958  op->item_power += get_power_from_ench(num_enchantments);
959  } else if (save_item_power) {
960  /* restore the item_power field to the object if we haven't changed
961  * it. we don't care about num_enchantments - that will basically
962  * just have calculated some value from the base attributes of the
963  * archetype.
964  */
965  op->item_power = save_item_power;
966  } else {
967  /* item_power was zero. This is suspicious, as it may be because it
968  * was never previously calculated. Let's compute a value and see if
969  * it is non-zero. If it indeed is, then assign it as the new
970  * item_power value.
971  * - gros, 21th of July 2006.
972  */
973  op->item_power = calc_item_power(op);
974  save_item_power = op->item_power; /* Just in case it would get used
975  * again below */
976  }
977  } else {
978  /* If flag is GT_MINIMAL, we want to restore item power */
979  op->item_power = save_item_power;
980  }
981 
982  /* materialtype modifications. Note we allow this on artifacts. */
984 
985  if (flags&GT_MINIMAL) {
986  if (op->type == POTION)
987  /* Handle healing and magic power potions */
988  if (op->stats.sp && !op->randomitems) {
989  object *tmp;
990  if (spell_mapping[op->stats.sp]) {
991  tmp = create_archetype(spell_mapping[op->stats.sp]);
993  }
994  op->stats.sp = 0;
995  }
996  } else if (!op->title) { /* Only modify object if not special */
997  switch (op->type) {
998  case WEAPON:
999  case ARMOUR:
1000  case SHIELD:
1001  case HELMET:
1002  case CLOAK:
1003  if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4))
1004  set_ring_bonus(op, -DICE2);
1005  break;
1006 
1007  case BRACERS:
1008  if (!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED) ? 5 : 20))) {
1010  if (!QUERY_FLAG(op, FLAG_CURSED))
1011  op->value *= 3;
1012  }
1013  break;
1014 
1015  case POTION: {
1016  int too_many_tries = 0, is_special = 0;
1017 
1018  /* Handle healing and magic power potions */
1019  if (op->stats.sp && !op->randomitems) {
1020  object *tmp;
1021 
1022  tmp = create_archetype(spell_mapping[op->stats.sp]);
1024  op->stats.sp = 0;
1025  }
1026 
1027  while (!(is_special = special_potion(op)) && !op->inv) {
1028  generate_artifact(op, difficulty);
1029  if (too_many_tries++ > 10)
1030  break;
1031  }
1032  /* don't want to change value for healing/magic power potions,
1033  * since the value set on those is already correct.
1034  */
1035  if (op->inv && op->randomitems) {
1036  /* value multiplier is same as for scrolls */
1037  op->value = (op->value*op->inv->value);
1038  op->level = op->inv->level/2+RANDOM()%difficulty+RANDOM()%difficulty;
1039  } else {
1040  FREE_AND_COPY(op->name, "potion");
1041  FREE_AND_COPY(op->name_pl, "potions");
1042  }
1043  if (!(flags&GT_ONLY_GOOD) && RANDOM()%2)
1045  break;
1046  }
1047 
1048  case AMULET:
1049  if (op->arch == amulet_arch)
1050  op->value *= 5; /* Since it's not just decoration */
1051  /* fall through */
1052  case RING:
1053  if (op->arch == NULL) {
1054  object_remove(op);
1056  op = NULL;
1057  break;
1058  }
1059  if (op->arch != ring_arch && op->arch != amulet_arch)
1060  /* It's a special artifact!*/
1061  break;
1062 
1063  if (GET_ANIM_ID(op))
1064  SET_ANIMATION(op, RANDOM()%((int)NUM_ANIMATIONS(op)));
1065  if (!(flags&GT_ONLY_GOOD) && !(RANDOM()%3))
1068  if (op->type != RING) /* Amulets have only one ability */
1069  break;
1070  if (!(RANDOM()%4)) {
1071  int d = (RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1072  if (d > 0)
1073  op->value *= 3;
1074  set_ring_bonus(op, d);
1075  if (!(RANDOM()%4)) {
1076  int d = (RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1077  if (d > 0)
1078  op->value *= 5;
1079  set_ring_bonus(op, d);
1080  }
1081  }
1082  break;
1083 
1084  case BOOK:
1085  /* Is it an empty book?, if yes lets make a special
1086  * msg for it, and tailor its properties based on the
1087  * creator and/or map level we found it on.
1088  */
1089  if (!op->msg && RANDOM()%10) {
1090  /* set the book level properly */
1091  if (creator->level == 0 || QUERY_FLAG(creator, FLAG_ALIVE)) {
1092  if (op->map && op->map->difficulty)
1093  op->level = RANDOM()%(op->map->difficulty)+RANDOM()%10+1;
1094  else
1095  op->level = RANDOM()%20+1;
1096  } else
1097  op->level = RANDOM()%creator->level;
1098 
1099  tailor_readable_ob(op, creator->stats.sp);
1100  /* books w/ info are worth more! */
1101  if (op->msg != NULL)
1102  op->value *= ((op->level > 10 ? op->level : (op->level+1)/2)*((strlen(op->msg)/250)+1));
1103  /* creator related stuff */
1104 
1105  if (creator->slaying && !op->slaying) /* for check_inv floors */
1106  op->slaying = add_string(creator->slaying);
1107 
1108  /* add exp so reading it gives xp (once)*/
1109  op->stats.exp = op->value > 10000 ? op->value/5 : op->value/10;
1110  }
1111  /* for library, chained books. Note that some monsters have
1112  * no_pick set - we don't want to set no pick in that case. */
1113  if (QUERY_FLAG(creator, FLAG_NO_PICK)
1114  && !QUERY_FLAG(creator, FLAG_MONSTER))
1116  break;
1117 
1118  case SPELLBOOK:
1119  op->value = op->value*op->inv->value;
1120  /* add exp so learning gives xp */
1121  op->level = op->inv->level;
1122  op->stats.exp = op->value;
1123  /* some more fun */
1124  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 5) {
1125  if (rndm(1, 6) <= 1)
1127  else
1129  } else if (rndm(1, 100) <= 1) {
1131  }
1132  break;
1133 
1134  case WAND:
1135  /* nrof in the treasure list is number of charges,
1136  * not number of wands. So copy that into food (charges),
1137  * and reset nrof.
1138  */
1139  op->stats.food = op->inv->nrof;
1140  op->nrof = 1;
1141  /* If the spell changes by level, choose a random level
1142  * for it, and adjust price. If the spell doesn't
1143  * change by level, just set the wand to the level of
1144  * the spell, and value calculation is simpler.
1145  */
1146  if (op->inv->duration_modifier
1147  || op->inv->dam_modifier
1148  || op->inv->range_modifier) {
1149  op->level = level_for_item(op, difficulty);
1150  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1151  } else {
1152  op->level = op->inv->level;
1153  op->value = op->value*op->inv->value;
1154  }
1155  break;
1156 
1157  case ROD:
1158  op->level = level_for_item(op, difficulty);
1159  rod_adjust(op);
1160  break;
1161 
1162  case SCROLL:
1163  op->level = level_for_item(op, difficulty);
1164  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1165  /* add exp so reading them properly gives xp */
1166  op->stats.exp = op->value/5;
1167  op->nrof = op->inv->nrof;
1168  /* some more fun */
1169  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 20) {
1170  if (rndm(1, 6) <= 1)
1172  else
1174  } else if (rndm(1, 100) <= 2) {
1176  }
1177  break;
1178 
1179  case RUNE:
1180  trap_adjust(op, difficulty);
1181  break;
1182 
1183  case TRAP:
1184  trap_adjust(op, difficulty);
1185  break;
1186  } /* switch type */
1187  }
1188  if (flags&GT_STARTEQUIP) {
1189  if (op->nrof < 2
1190  && op->type != CONTAINER
1191  && op->type != MONEY
1194  else if (op->type != MONEY)
1195  op->value = 0;
1196  }
1197 
1198  if (!(flags&GT_ENVIRONMENT))
1199  fix_flesh_item(op, creator);
1200 }
1201 
1205 static void dump_monster_treasure_rec(const char *name, treasure *t, int depth) {
1206  treasurelist *tl;
1207  int i;
1208 
1209  if (depth > 100)
1210  return;
1211 
1212  while (t != NULL) {
1213  if (t->name != NULL) {
1214  for (i = 0; i < depth; i++)
1215  fprintf(logfile, " ");
1216  fprintf(logfile, "{ (list: %s)\n", t->name);
1217  tl = find_treasurelist(t->name);
1218  dump_monster_treasure_rec(name, tl->items, depth+2);
1219  for (i = 0; i < depth; i++)
1220  fprintf(logfile, " ");
1221  fprintf(logfile, "} (end of list: %s)\n", t->name);
1222  } else {
1223  for (i = 0; i < depth; i++)
1224  fprintf(logfile, " ");
1225  if (t->item->clone.type == FLESH)
1226  fprintf(logfile, "%s's %s\n", name, t->item->clone.name);
1227  else
1228  fprintf(logfile, "%s\n", t->item->clone.name);
1229  }
1230  if (t->next_yes != NULL) {
1231  for (i = 0; i < depth; i++)
1232  fprintf(logfile, " ");
1233  fprintf(logfile, " (if yes)\n");
1234  dump_monster_treasure_rec(name, t->next_yes, depth+1);
1235  }
1236  if (t->next_no != NULL) {
1237  for (i = 0; i < depth; i++)
1238  fprintf(logfile, " ");
1239  fprintf(logfile, " (if no)\n");
1240  dump_monster_treasure_rec(name, t->next_no, depth+1);
1241  }
1242  t = t->next;
1243  }
1244 }
1245 
1250 void dump_monster_treasure(const char *name) {
1251  int found;
1252 
1253  found = 0;
1254  fprintf(logfile, "\n");
1255  getManager()->archetypes()->each([&] (const auto at) {
1256  if (!strcasecmp(at->clone.name, name) && at->clone.title == NULL) {
1257  fprintf(logfile, "treasures for %s (arch: %s)\n", at->clone.name, at->name);
1258  if (at->clone.randomitems != NULL)
1259  dump_monster_treasure_rec(at->clone.name, at->clone.randomitems->items, 1);
1260  else
1261  fprintf(logfile, "(nothing)\n");
1262  fprintf(logfile, "\n");
1263  found++;
1264  }
1265  });
1266 
1267  if (found == 0)
1268  fprintf(logfile, "No objects have the name %s!\n\n", name);
1269 }
1270 
1278 static void fix_flesh_item(object *item, const object *donor) {
1279  char tmpbuf[MAX_BUF];
1280  int i;
1281 
1282  if (item->type == FLESH && donor && QUERY_FLAG(donor, FLAG_MONSTER)) {
1283  /* change the name */
1284  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name);
1285  FREE_AND_COPY(item->name, tmpbuf);
1286  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name_pl);
1287  FREE_AND_COPY(item->name_pl, tmpbuf);
1288 
1289  /* store original arch in other_arch */
1290  if (!item->other_arch) {
1291  if (!donor->arch->reference_count) {
1292  item->other_arch = donor->arch;
1293  } else {
1294  /* If dealing with custom monsters, other_arch still needs to
1295  * point back to the original. Otherwise what happens
1296  * is that other_arch points at the custom archetype, but
1297  * that can be freed. Reference count doesn't work because
1298  * the loader will not be able to resolve the other_arch at
1299  * load time (server may has restarted, etc.)
1300  */
1301  archetype *original = find_archetype(donor->arch->name);
1302 
1303  if (original)
1304  item->other_arch = original;
1305  else {
1306  LOG(llevError, "could not find original archetype %s for custom monster!\n", donor->arch->name);
1307  abort();
1308  }
1309  }
1310  }
1311 
1312  /* weight is FLESH weight/100 * donor */
1313  if ((item->weight = (signed long)(((double)item->weight/(double)100.0)*(double)donor->weight)) == 0)
1314  item->weight = 1;
1315 
1316  /* value is multiplied by level of donor */
1317  item->value *= isqrt(donor->level*2);
1318 
1319  /* food value */
1320  item->stats.food += (donor->stats.hp/100)+donor->stats.Con;
1321 
1322  /* flesh items inherit some abilities of donor, but not full effect. */
1323  for (i = 0; i < NROFATTACKS; i++)
1324  item->resist[i] = donor->resist[i]/2;
1325 
1326  /* item inherits donor's level and exp (important for dragons) */
1327  item->level = donor->level;
1328  item->stats.exp = donor->stats.exp;
1329 
1330  /* if donor has some attacktypes, the flesh is poisonous */
1331  if (donor->attacktype&AT_POISON)
1332  item->type = POISON;
1333  if (donor->attacktype&AT_ACID)
1334  item->stats.hp = -1*item->stats.food;
1336 
1337  /* attempt to change the face - will take a face named "donor's arch"_"item's face". We ignore the animation for now */
1338  if (item->face != NULL) {
1339  snprintf(tmpbuf, sizeof(tmpbuf), "%s_%s", donor->arch->name, item->face->name);
1340  item->face = try_find_face(tmpbuf, item->face);
1341  }
1342  }
1343 }
1344 
1353 static int special_potion(object *op) {
1354  int i;
1355 
1356  if (op->attacktype)
1357  return 1;
1358 
1359  if (op->stats.Str
1360  || op->stats.Dex
1361  || op->stats.Con
1362  || op->stats.Pow
1363  || op->stats.Wis
1364  || op->stats.Int
1365  || op->stats.Cha)
1366  return 1;
1367 
1368  for (i = 0; i < NROFATTACKS; i++)
1369  if (op->resist[i])
1370  return 1;
1371 
1372  return 0;
1373 }
1374 
1387  treasure *t = (treasure *)calloc(1, sizeof(treasure));
1388  if (t == NULL)
1390  t->item = NULL;
1391  t->name = NULL;
1392  t->next = NULL;
1393  t->next_yes = NULL;
1394  t->next_no = NULL;
1395  t->chance = 100;
1396  t->magic = 0;
1397  t->nrof = 0;
1398  return t;
1399 }
1400 
1408  if (t->name)
1409  free_string(t->name);
1410  if (t->artifact)
1411  free_string(t->artifact);
1412  if (t->next)
1413  treasure_free(t->next);
1414  if (t->next_yes)
1415  treasure_free(t->next_yes);
1416  if (t->next_no)
1417  treasure_free(t->next_no);
1418  free(t);
1419 }
1420 
1421 
1429  treasure *added = get_empty_treasure();
1430  if (list->items == NULL || position <= 0) {
1431  added->next = list->items;
1432  list->items = added;
1433  return added;
1434  }
1435  treasure *prev = list->items;
1436  position--;
1437  while (position > 0 && prev->next) {
1438  position--;
1439  prev = prev->next;
1440  }
1441  added->next = prev->next;
1442  prev->next = added;
1443  return added;
1444 }
1445 
1452  if (list->items == 0 || position < 0) {
1453  return;
1454  }
1455  if (position == 0) {
1456  treasure *next = list->items->next;
1457  list->items->next = NULL;
1458  treasure_free(list->items);
1459  list->items = next;
1460  return;
1461  }
1462  position--;
1463  treasure *prev = list->items;
1464  while (prev && position > 0) {
1465  position--;
1466  prev = prev->next;
1467  }
1468  if (!prev) {
1469  return;
1470  }
1471  treasure *next = prev->next->next;
1472  prev->next->next = NULL;
1473  treasure_free(prev->next);
1474  prev->next = next;
1475 }
give.next
def next
Definition: give.py:44
living::exp
int64_t exp
Definition: living.h:47
ATNR_PARALYZE
#define ATNR_PARALYZE
Definition: attack.h:61
set_magic
static void set_magic(int difficulty, object *op, int max_magic, int flags)
Definition: treasure.cpp:666
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:545
settings
struct Settings settings
Definition: init.cpp:139
set_abs_magic
void set_abs_magic(object *op, int magic)
Definition: treasure.cpp:618
dump_monster_treasure_rec
static void dump_monster_treasure_rec(const char *name, treasure *t, int depth)
Definition: treasure.cpp:1205
INS_NO_WALK_ON
#define INS_NO_WALK_ON
Definition: object.h:582
AT_POISON
#define AT_POISON
Definition: attack.h:86
BRACERS
@ BRACERS
Definition: object.h:222
find_artifact
const artifact * find_artifact(const object *op, const char *name)
Definition: artifact.cpp:589
llevError
@ llevError
Definition: logger.h:11
DICE2
#define DICE2
Definition: treasure.cpp:880
FABS
#define FABS(x)
Definition: define.h:22
WAND
@ WAND
Definition: object.h:225
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
Settings::armor_speed_linear
uint8_t armor_speed_linear
Definition: global.h:309
FLESH
@ FLESH
Definition: object.h:192
object::inv
object * inv
Definition: object.h:298
ATNR_ACID
#define ATNR_ACID
Definition: attack.h:55
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Definition: define.h:268
num_resist_table
#define num_resist_table
Definition: treasure.cpp:53
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
FLAG_REFL_MISSILE
#define FLAG_REFL_MISSILE
Definition: define.h:273
treasurelist::items
treasure * items
Definition: treasure.h:92
AssetsManager.h
level_for_item
static int level_for_item(const object *op, int difficulty)
Definition: treasure.cpp:323
object::arch
struct archetype * arch
Definition: object.h:424
if
if(!(yy_init))
Definition: loader.cpp:36428
treasurelist::total_chance
int16_t total_chance
Definition: treasure.h:87
FLAG_OBJ_ORIGINAL
#define FLAG_OBJ_ORIGINAL
Definition: define.h:357
TRAP
@ TRAP
Definition: object.h:246
object::x
int16_t x
Definition: object.h:335
ARMOUR
@ ARMOUR
Definition: object.h:125
guildoracle.list
list
Definition: guildoracle.py:87
give_artifact_abilities
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.cpp:230
object::map
struct mapstruct * map
Definition: object.h:305
WEAPON
@ WEAPON
Definition: object.h:124
guildjoin.ob
ob
Definition: guildjoin.py:42
GT_ONLY_GOOD
@ GT_ONLY_GOOD
Definition: treasure.h:34
artifact::item
object * item
Definition: artifact.h:15
SET_ANIMATION
#define SET_ANIMATION(ob, newanim)
Definition: global.h:162
ATNR_SLOW
#define ATNR_SLOW
Definition: attack.h:60
AMULET
@ AMULET
Definition: object.h:144
fix_generated_item
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.cpp:909
get_power_from_ench
int get_power_from_ench(int ench)
Definition: item.cpp:212
flags
static const flag_definition flags[]
Definition: gridarta-types-convert.cpp:101
MAXMAGIC
#define MAXMAGIC
Definition: treasure.h:13
RUNE
@ RUNE
Definition: object.h:245
set_materialname
void set_materialname(object *op)
Definition: utils.cpp:297
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:249
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.cpp:390
ATNR_PHYSICAL
#define ATNR_PHYSICAL
Definition: attack.h:49
ARMOUR_SPEED
#define ARMOUR_SPEED(xyz)
Definition: define.h:466
special_potion
static int special_potion(object *op)
Definition: treasure.cpp:1353
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.cpp:175
rndm
int rndm(int min, int max)
Definition: utils.cpp:162
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.cpp:263
object::level
int16_t level
Definition: object.h:361
get_magic
static int get_magic(int diff)
Definition: treasure.cpp:821
GT_STARTEQUIP
@ GT_STARTEQUIP
Definition: treasure.h:33
getManager
AssetsManager * getManager()
Definition: assets.cpp:305
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2853
AT_DEATH
#define AT_DEATH
Definition: attack.h:93
object::resist
int16_t resist[NROFATTACKS]
Definition: object.h:351
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
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
ATNR_BLIND
#define ATNR_BLIND
Definition: attack.h:71
object::y
int16_t y
Definition: object.h:335
CLOAK
@ CLOAK
Definition: object.h:209
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1560
HELMET
@ HELMET
Definition: object.h:141
POISON
@ POISON
Definition: object.h:118
magic_from_difficulty
static int magic_from_difficulty(int difficulty)
Definition: treasure.cpp:578
trap_adjust
static void trap_adjust(object *trap, int difficulty)
Definition: treasure.cpp:842
init_archetype_pointers
void init_archetype_pointers(void)
Definition: treasure.cpp:62
amulet_arch
static archetype * amulet_arch
Definition: treasure.cpp:50
POTION
@ POTION
Definition: object.h:116
GT_INVISIBLE
@ GT_INVISIBLE
Definition: treasure.h:32
do_single_item
static void do_single_item(treasure *t, object *op, int flag, int difficulty)
Definition: treasure.cpp:139
treasurelist
Definition: treasure.h:85
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
ROD
@ ROD
Definition: object.h:114
CONTAINER
@ CONTAINER
Definition: object.h:236
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
Definition: living.cpp:218
treasure_free
void treasure_free(treasure *t)
Definition: treasure.cpp:1407
tailor_readable_ob
void tailor_readable_ob(object *book, int msg_type)
Definition: readable.cpp:1892
change_treasure
static void change_treasure(treasure *t, object *op)
Definition: treasure.cpp:105
Settings::armor_weight_reduction
int armor_weight_reduction
Definition: global.h:306
isqrt
int isqrt(int n)
Definition: utils.cpp:562
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Definition: global.h:204
Ice.b
b
Definition: Ice.py:48
object::type
uint8_t type
Definition: object.h:348
INS_NO_MERGE
#define INS_NO_MERGE
Definition: object.h:580
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
living::dam
int16_t dam
Definition: living.h:46
ATNR_DRAIN
#define ATNR_DRAIN
Definition: attack.h:56
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1592
archetype
Definition: object.h:483
ATNR_POISON
#define ATNR_POISON
Definition: attack.h:59
sproto.h
resist_table
static int resist_table[]
Definition: treasure.cpp:39
logfile
FILE * logfile
Definition: init.cpp:114
ATNR_DEATH
#define ATNR_DEATH
Definition: attack.h:66
living::sp
int16_t sp
Definition: living.h:42
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
FLAG_NO_STEAL
#define FLAG_NO_STEAL
Definition: define.h:342
GET_ANIM_ID
#define GET_ANIM_ID(ob)
Definition: global.h:165
BOOK
@ BOOK
Definition: object.h:119
GT_ENVIRONMENT
@ GT_ENVIRONMENT
Definition: treasure.h:31
RING
@ RING
Definition: object.h:190
set_ring_bonus
static void set_ring_bonus(object *op, int bonus)
Definition: treasure.cpp:695
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.cpp:2100
object::other_arch
struct archetype * other_arch
Definition: object.h:425
treasure::next
treasure * next
Definition: treasure.h:69
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:590
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
treasure.h
MAX_BUF
#define MAX_BUF
Definition: define.h:35
object_new
object * object_new(void)
Definition: object.cpp:1273
treasure_remove_item
void treasure_remove_item(treasurelist *list, int position)
Definition: treasure.cpp:1451
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:278
object::weight
int32_t weight
Definition: object.h:375
free_string
void free_string(sstring str)
Definition: shstr.cpp:280
RANDOM
#define RANDOM()
Definition: define.h:644
difftomagic_list
static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1]
Definition: treasure.cpp:365
ATNR_FIRE
#define ATNR_FIRE
Definition: attack.h:51
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
put_treasure
static void put_treasure(object *op, object *creator, int flags)
Definition: treasure.cpp:82
FLAG_REFL_SPELL
#define FLAG_REFL_SPELL
Definition: define.h:275
Floor.t
t
Definition: Floor.py:62
object::slaying
sstring slaying
Definition: object.h:327
object::name
sstring name
Definition: object.h:319
get_empty_treasure
treasure * get_empty_treasure(void)
Definition: treasure.cpp:1386
ATNR_DEPLETE
#define ATNR_DEPLETE
Definition: attack.h:65
item
Definition: item.py:1
living::Cha
int8_t Cha
Definition: living.h:36
give.op
op
Definition: give.py:33
autojail.value
value
Definition: autojail.py:6
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:266
spell_mapping
const char *const spell_mapping[SPELL_MAPPINGS]
Definition: object.cpp:74
archetype::reference_count
int reference_count
Definition: object.h:490
ATNR_MAGIC
#define ATNR_MAGIC
Definition: attack.h:50
assets.h
CHANCE_FOR_ARTIFACT
#define CHANCE_FOR_ARTIFACT
Definition: treasure.h:10
fix_flesh_item
static void fix_flesh_item(object *item, const object *donor)
Definition: treasure.cpp:1278
NUM_ANIMATIONS
#define NUM_ANIMATIONS(ob)
Definition: global.h:171
treasure_insert
treasure * treasure_insert(treasurelist *list, int position)
Definition: treasure.cpp:1428
dump_monster_treasure
void dump_monster_treasure(const char *name)
Definition: treasure.cpp:1250
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:229
level
int level
Definition: readable.cpp:1563
DIFFLEVELS
#define DIFFLEVELS
Definition: treasure.h:16
Settings::armor_weight_linear
uint8_t armor_weight_linear
Definition: global.h:307
strcasecmp
int strcasecmp(const char *s1, const char *s2)
make_face_from_files.int
int
Definition: make_face_from_files.py:32
AT_ACID
#define AT_ACID
Definition: attack.h:82
loader.h
object_remove
void object_remove(object *op)
Definition: object.cpp:1833
try_find_face
const Face * try_find_face(const char *name, const Face *error)
Definition: assets.cpp:286
crown_arch
static archetype * crown_arch
Definition: treasure.cpp:50
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.cpp:295
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:544
ATNR_GHOSTHIT
#define ATNR_GHOSTHIT
Definition: attack.h:58
ATNR_COLD
#define ATNR_COLD
Definition: attack.h:53
archetype::name
sstring name
Definition: object.h:484
SCROLL
@ SCROLL
Definition: object.h:226
create_one_treasure
static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries)
Definition: treasure.cpp:210
object::stats
living stats
Definition: object.h:378
treasure
Definition: treasure.h:63
artifact
Definition: artifact.h:14
get_attr_value
int8_t get_attr_value(const living *stats, int attr)
Definition: living.cpp:313
calc_item_power
int calc_item_power(const object *op)
Definition: item.cpp:235
ATNR_ELECTRICITY
#define ATNR_ELECTRICITY
Definition: attack.h:52
SPELL
@ SPELL
Definition: object.h:219
ring_arch
static archetype * ring_arch
Definition: treasure.cpp:50
SHIELD
@ SHIELD
Definition: object.h:140
object::attacktype
uint32_t attacktype
Definition: object.h:352
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
ATNR_LIFE_STEALING
#define ATNR_LIFE_STEALING
Definition: attack.h:73
generate_artifact
void generate_artifact(object *op, int difficulty)
Definition: artifact.cpp:177
FLAG_IS_THROWN
#define FLAG_IS_THROWN
Definition: define.h:249
Settings::armor_speed_improvement
int armor_speed_improvement
Definition: global.h:308
SPELLBOOK
@ SPELLBOOK
Definition: object.h:208
GT_MINIMAL
@ GT_MINIMAL
Definition: treasure.h:36
living::hp
int16_t hp
Definition: living.h:40
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
llevDebug
@ llevDebug
Definition: logger.h:13
MONEY
@ MONEY
Definition: object.h:142
living::Con
int8_t Con
Definition: living.h:36
give.name
name
Definition: give.py:27
legal_artifact_combination
int legal_artifact_combination(const object *op, const artifact *art)
Definition: artifact.cpp:252
ATNR_FEAR
#define ATNR_FEAR
Definition: attack.h:63
level
Definition: level.py:1