Crossfire Server  1.75.0
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) {
109  /* not great, but better than something that is completely wrong */
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);
123  }
124 }
125 
139 static bool do_single_item(treasure *t, object *op, int flag, int difficulty) {
140  if (!(t->item))
141  return false;
142 
143  object *tmp = arch_to_object(t->item);
144  if (t->nrof && tmp->nrof <= 1)
145  tmp->nrof = RANDOM()%((int)t->nrof)+1;
146  if (t->artifact) {
147  const artifact *art = find_artifact(tmp, t->artifact);
148  if (!art || !legal_artifact_combination(tmp, art)) {
149  LOG(llevError, "Invalid artifact %s for treasure %s\n", t->artifact, tmp->arch->name);
150  goto reject;
151  } else {
152  give_artifact_abilities(tmp, art->item);
153  }
154  } else {
155  fix_generated_item(tmp, op, difficulty, t->magic, flag);
156  change_treasure(t, tmp);
157  }
158 
159  // We need to apply artifact changes before we know the properties of the final item. Previous
160  // versions of this code only checked the arch 'clone' object, which is not correct.
161  if (flag&GT_ONLY_GOOD && (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)))
162  goto reject;
163 
164  if (op->type == SHOP_FLOOR && price_base(tmp) < (op->map ? MAX(op->map->shopmin, 1) : 1))
165  goto reject;
166 
167  if (flag&GT_INVISIBLE && tmp->invisible)
168  goto reject;
169 
170  put_treasure(tmp, op, flag);
171  return true;
172 
173 reject:
175  return false;
176 }
177 
193 static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries) {
194  if (chance(t->chance, 100)) {
195  if (t->name) {
196  if (strcmp(t->name, "NONE") && difficulty >= t->magic)
197  create_treasure(find_treasurelist(t->name), op, flag, t->list_magic_value ? t->list_magic_value : difficulty + t->list_magic_adjustment, tries);
198  } else {
199  while (tries < 100) {
200  if (do_single_item(t, op, flag, difficulty))
201  break;
202  tries++;
203  }
204  }
205  if (t->next_yes != NULL)
206  create_all_treasures(t->next_yes, op, flag, difficulty, tries);
207  } else
208  if (t->next_no != NULL)
209  create_all_treasures(t->next_no, op, flag, difficulty, tries);
210  if (t->next != NULL)
211  create_all_treasures(t->next, op, flag, difficulty, tries);
212 }
213 
232 static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries) {
233  int value = RANDOM()%tl->total_chance;
234  treasure *t;
235 
236  if (tries++ > 100) {
237  LOG(llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
238  return;
239  }
240 
241  for (t = tl->items; t != NULL; t = t->next) {
242  value -= t->chance;
243  if (value < 0)
244  break;
245  }
246 
247  if (!t || value >= 0) {
248  LOG(llevError, "create_one_treasure: got null object or not able to find treasure\n");
249  abort();
250  }
251  if (t->name) {
252  if (!strcmp(t->name, "NONE"))
253  return;
254  if (difficulty >= t->magic)
255  create_treasure(find_treasurelist(t->name), op, flag, t->list_magic_value ? t->list_magic_value : difficulty + t->list_magic_adjustment, tries);
256  else if (t->nrof)
257  create_one_treasure(tl, op, flag, difficulty, tries);
258  return;
259  }
260  bool got_one = false;
261  while (tries < 100) {
262  if (do_single_item(t, op, flag, difficulty)) {
263  got_one = true;
264  break;
265  }
266  tries++;
267  }
268  if (!got_one)
269  LOG(llevError, "create_one_treasure failed to create at least one treasure for item %s on list %s\n", t->item->name, tl->name);
270 }
271 
287 void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries) {
288  if (tries++ > 100) {
289  LOG(llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
290  return;
291  }
292  if (!t->items) {
293  LOG(llevError, "Empty treasure list %s\n", t->name);
294  return;
295  }
296  if (t->total_chance)
297  create_one_treasure(t, op, flag, difficulty, tries);
298  else
299  create_all_treasures(t->items, op, flag, difficulty, tries);
300 }
301 
319 object *generate_treasure(treasurelist *t, int difficulty) {
320  object *ob = object_new(), *tmp;
321 
322  create_treasure(t, ob, 0, difficulty, 0);
323 
324  /* Don't want to free the object we are about to return */
325  tmp = ob->inv;
326  if (tmp != NULL)
327  object_remove(tmp);
328  if (ob->inv) {
329  LOG(llevError, "In generate treasure, created multiple objects.\n");
330  }
332  return tmp;
333 }
334 
347 static int level_for_item(const object *op, int difficulty) {
348  int level, mult, olevel;
349 
350  if (!op->inv) {
351  LOG(llevError, "level_for_item: Object %s has no inventory!\n", op->name);
352  return 0;
353  }
354  level = op->inv->level;
355 
356  /* Basically, we set mult to the lowest spell increase attribute that is
357  * not zero - zero's mean no modification is done, so we don't want those.
358  * given we want non zero results, we can't just use a few MIN's here.
359  */
360  mult = op->inv->dam_modifier;
361  if (op->inv->range_modifier && (op->inv->range_modifier < mult || mult == 0))
362  mult = op->inv->range_modifier;
363  if (op->inv->duration_modifier && (op->inv->duration_modifier < mult || mult == 0))
364  mult = op->inv->duration_modifier;
365 
366  if (mult == 0)
367  mult = 5;
368 
369  // This should give us roughly a normal distribution averaged at difficulty.
370  olevel = rndm(0, difficulty)+rndm(0, difficulty);
371  // Now we truncate to the closest level + n * mult value below.
372  olevel = ((olevel-level)/mult)*mult+level; // This should truncate to a multiple of mult for us.
373  if (olevel > MAX_SPELLITEM_LEVEL)
374  olevel = MAX_SPELLITEM_LEVEL;
375  // Make sure we hit the minimum spell level, too
376  else if (olevel < level)
377  olevel = level;
378 
379  return olevel;
380 }
381 
389 static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1] = {
390 /*chance of magic difficulty*/
391 /* +0 +1 +2 +3 +4 */
392  { 94, 3, 2, 1, 0 }, /*1*/
393  { 94, 3, 2, 1, 0 }, /*2*/
394  { 94, 3, 2, 1, 0 }, /*3*/
395  { 94, 3, 2, 1, 0 }, /*4*/
396  { 94, 3, 2, 1, 0 }, /*5*/
397  { 90, 4, 3, 2, 1 }, /*6*/
398  { 90, 4, 3, 2, 1 }, /*7*/
399  { 90, 4, 3, 2, 1 }, /*8*/
400  { 90, 4, 3, 2, 1 }, /*9*/
401  { 90, 4, 3, 2, 1 }, /*10*/
402  { 85, 6, 4, 3, 2 }, /*11*/
403  { 85, 6, 4, 3, 2 }, /*12*/
404  { 85, 6, 4, 3, 2 }, /*13*/
405  { 85, 6, 4, 3, 2 }, /*14*/
406  { 85, 6, 4, 3, 2 }, /*15*/
407  { 81, 8, 5, 4, 3 }, /*16*/
408  { 81, 8, 5, 4, 3 }, /*17*/
409  { 81, 8, 5, 4, 3 }, /*18*/
410  { 81, 8, 5, 4, 3 }, /*19*/
411  { 81, 8, 5, 4, 3 }, /*20*/
412  { 75, 10, 6, 5, 4 }, /*21*/
413  { 75, 10, 6, 5, 4 }, /*22*/
414  { 75, 10, 6, 5, 4 }, /*23*/
415  { 75, 10, 6, 5, 4 }, /*24*/
416  { 75, 10, 6, 5, 4 }, /*25*/
417  { 70, 12, 7, 6, 5 }, /*26*/
418  { 70, 12, 7, 6, 5 }, /*27*/
419  { 70, 12, 7, 6, 5 }, /*28*/
420  { 70, 12, 7, 6, 5 }, /*29*/
421  { 70, 12, 7, 6, 5 }, /*30*/
422  { 70, 9, 8, 7, 6 }, /*31*/
423  { 70, 9, 8, 7, 6 }, /*32*/
424  { 70, 9, 8, 7, 6 }, /*33*/
425  { 70, 9, 8, 7, 6 }, /*34*/
426  { 70, 9, 8, 7, 6 }, /*35*/
427  { 70, 6, 9, 8, 7 }, /*36*/
428  { 70, 6, 9, 8, 7 }, /*37*/
429  { 70, 6, 9, 8, 7 }, /*38*/
430  { 70, 6, 9, 8, 7 }, /*39*/
431  { 70, 6, 9, 8, 7 }, /*40*/
432  { 70, 3, 10, 9, 8 }, /*41*/
433  { 70, 3, 10, 9, 8 }, /*42*/
434  { 70, 3, 10, 9, 8 }, /*43*/
435  { 70, 3, 10, 9, 8 }, /*44*/
436  { 70, 3, 10, 9, 8 }, /*45*/
437  { 70, 2, 9, 10, 9 }, /*46*/
438  { 70, 2, 9, 10, 9 }, /*47*/
439  { 70, 2, 9, 10, 9 }, /*48*/
440  { 70, 2, 9, 10, 9 }, /*49*/
441  { 70, 2, 9, 10, 9 }, /*50*/
442  { 70, 2, 7, 11, 10 }, /*51*/
443  { 70, 2, 7, 11, 10 }, /*52*/
444  { 70, 2, 7, 11, 10 }, /*53*/
445  { 70, 2, 7, 11, 10 }, /*54*/
446  { 70, 2, 7, 11, 10 }, /*55*/
447  { 70, 2, 5, 12, 11 }, /*56*/
448  { 70, 2, 5, 12, 11 }, /*57*/
449  { 70, 2, 5, 12, 11 }, /*58*/
450  { 70, 2, 5, 12, 11 }, /*59*/
451  { 70, 2, 5, 12, 11 }, /*60*/
452  { 70, 2, 3, 13, 12 }, /*61*/
453  { 70, 2, 3, 13, 12 }, /*62*/
454  { 70, 2, 3, 13, 12 }, /*63*/
455  { 70, 2, 3, 13, 12 }, /*64*/
456  { 70, 2, 3, 13, 12 }, /*65*/
457  { 70, 2, 3, 12, 13 }, /*66*/
458  { 70, 2, 3, 12, 13 }, /*67*/
459  { 70, 2, 3, 12, 13 }, /*68*/
460  { 70, 2, 3, 12, 13 }, /*69*/
461  { 70, 2, 3, 12, 13 }, /*70*/
462  { 70, 2, 3, 11, 14 }, /*71*/
463  { 70, 2, 3, 11, 14 }, /*72*/
464  { 70, 2, 3, 11, 14 }, /*73*/
465  { 70, 2, 3, 11, 14 }, /*74*/
466  { 70, 2, 3, 11, 14 }, /*75*/
467  { 70, 2, 3, 10, 15 }, /*76*/
468  { 70, 2, 3, 10, 15 }, /*77*/
469  { 70, 2, 3, 10, 15 }, /*78*/
470  { 70, 2, 3, 10, 15 }, /*79*/
471  { 70, 2, 3, 10, 15 }, /*80*/
472  { 70, 2, 3, 9, 16 }, /*81*/
473  { 70, 2, 3, 9, 16 }, /*82*/
474  { 70, 2, 3, 9, 16 }, /*83*/
475  { 70, 2, 3, 9, 16 }, /*84*/
476  { 70, 2, 3, 9, 16 }, /*85*/
477  { 70, 2, 3, 8, 17 }, /*86*/
478  { 70, 2, 3, 8, 17 }, /*87*/
479  { 70, 2, 3, 8, 17 }, /*88*/
480  { 70, 2, 3, 8, 17 }, /*89*/
481  { 70, 2, 3, 8, 17 }, /*90*/
482  { 70, 2, 3, 7, 18 }, /*91*/
483  { 70, 2, 3, 7, 18 }, /*92*/
484  { 70, 2, 3, 7, 18 }, /*93*/
485  { 70, 2, 3, 7, 18 }, /*94*/
486  { 70, 2, 3, 7, 18 }, /*95*/
487  { 70, 2, 3, 6, 19 }, /*96*/
488  { 70, 2, 3, 6, 19 }, /*97*/
489  { 70, 2, 3, 6, 19 }, /*98*/
490  { 70, 2, 3, 6, 19 }, /*99*/
491  { 70, 2, 3, 6, 19 }, /*100*/
492  { 70, 2, 3, 6, 19 }, /*101*/
493  { 70, 2, 3, 6, 19 }, /*101*/
494  { 70, 2, 3, 6, 19 }, /*102*/
495  { 70, 2, 3, 6, 19 }, /*103*/
496  { 70, 2, 3, 6, 19 }, /*104*/
497  { 70, 2, 3, 6, 19 }, /*105*/
498  { 70, 2, 3, 6, 19 }, /*106*/
499  { 70, 2, 3, 6, 19 }, /*107*/
500  { 70, 2, 3, 6, 19 }, /*108*/
501  { 70, 2, 3, 6, 19 }, /*109*/
502  { 70, 2, 3, 6, 19 }, /*110*/
503  { 70, 2, 3, 6, 19 }, /*111*/
504  { 70, 2, 3, 6, 19 }, /*112*/
505  { 70, 2, 3, 6, 19 }, /*113*/
506  { 70, 2, 3, 6, 19 }, /*114*/
507  { 70, 2, 3, 6, 19 }, /*115*/
508  { 70, 2, 3, 6, 19 }, /*116*/
509  { 70, 2, 3, 6, 19 }, /*117*/
510  { 70, 2, 3, 6, 19 }, /*118*/
511  { 70, 2, 3, 6, 19 }, /*119*/
512  { 70, 2, 3, 6, 19 }, /*120*/
513  { 70, 2, 3, 6, 19 }, /*121*/
514  { 70, 2, 3, 6, 19 }, /*122*/
515  { 70, 2, 3, 6, 19 }, /*123*/
516  { 70, 2, 3, 6, 19 }, /*124*/
517  { 70, 2, 3, 6, 19 }, /*125*/
518  { 70, 2, 3, 6, 19 }, /*126*/
519  { 70, 2, 3, 6, 19 }, /*127*/
520  { 70, 2, 3, 6, 19 }, /*128*/
521  { 70, 2, 3, 6, 19 }, /*129*/
522  { 70, 2, 3, 6, 19 }, /*130*/
523  { 70, 2, 3, 6, 19 }, /*131*/
524  { 70, 2, 3, 6, 19 }, /*132*/
525  { 70, 2, 3, 6, 19 }, /*133*/
526  { 70, 2, 3, 6, 19 }, /*134*/
527  { 70, 2, 3, 6, 19 }, /*135*/
528  { 70, 2, 3, 6, 19 }, /*136*/
529  { 70, 2, 3, 6, 19 }, /*137*/
530  { 70, 2, 3, 6, 19 }, /*138*/
531  { 70, 2, 3, 6, 19 }, /*139*/
532  { 70, 2, 3, 6, 19 }, /*140*/
533  { 70, 2, 3, 6, 19 }, /*141*/
534  { 70, 2, 3, 6, 19 }, /*142*/
535  { 70, 2, 3, 6, 19 }, /*143*/
536  { 70, 2, 3, 6, 19 }, /*144*/
537  { 70, 2, 3, 6, 19 }, /*145*/
538  { 70, 2, 3, 6, 19 }, /*146*/
539  { 70, 2, 3, 6, 19 }, /*147*/
540  { 70, 2, 3, 6, 19 }, /*148*/
541  { 70, 2, 3, 6, 19 }, /*149*/
542  { 70, 2, 3, 6, 19 }, /*150*/
543  { 70, 2, 3, 6, 19 }, /*151*/
544  { 70, 2, 3, 6, 19 }, /*152*/
545  { 70, 2, 3, 6, 19 }, /*153*/
546  { 70, 2, 3, 6, 19 }, /*154*/
547  { 70, 2, 3, 6, 19 }, /*155*/
548  { 70, 2, 3, 6, 19 }, /*156*/
549  { 70, 2, 3, 6, 19 }, /*157*/
550  { 70, 2, 3, 6, 19 }, /*158*/
551  { 70, 2, 3, 6, 19 }, /*159*/
552  { 70, 2, 3, 6, 19 }, /*160*/
553  { 70, 2, 3, 6, 19 }, /*161*/
554  { 70, 2, 3, 6, 19 }, /*162*/
555  { 70, 2, 3, 6, 19 }, /*163*/
556  { 70, 2, 3, 6, 19 }, /*164*/
557  { 70, 2, 3, 6, 19 }, /*165*/
558  { 70, 2, 3, 6, 19 }, /*166*/
559  { 70, 2, 3, 6, 19 }, /*167*/
560  { 70, 2, 3, 6, 19 }, /*168*/
561  { 70, 2, 3, 6, 19 }, /*169*/
562  { 70, 2, 3, 6, 19 }, /*170*/
563  { 70, 2, 3, 6, 19 }, /*171*/
564  { 70, 2, 3, 6, 19 }, /*172*/
565  { 70, 2, 3, 6, 19 }, /*173*/
566  { 70, 2, 3, 6, 19 }, /*174*/
567  { 70, 2, 3, 6, 19 }, /*175*/
568  { 70, 2, 3, 6, 19 }, /*176*/
569  { 70, 2, 3, 6, 19 }, /*177*/
570  { 70, 2, 3, 6, 19 }, /*178*/
571  { 70, 2, 3, 6, 19 }, /*179*/
572  { 70, 2, 3, 6, 19 }, /*180*/
573  { 70, 2, 3, 6, 19 }, /*181*/
574  { 70, 2, 3, 6, 19 }, /*182*/
575  { 70, 2, 3, 6, 19 }, /*183*/
576  { 70, 2, 3, 6, 19 }, /*184*/
577  { 70, 2, 3, 6, 19 }, /*185*/
578  { 70, 2, 3, 6, 19 }, /*186*/
579  { 70, 2, 3, 6, 19 }, /*187*/
580  { 70, 2, 3, 6, 19 }, /*188*/
581  { 70, 2, 3, 6, 19 }, /*189*/
582  { 70, 2, 3, 6, 19 }, /*190*/
583  { 70, 2, 3, 6, 19 }, /*191*/
584  { 70, 2, 3, 6, 19 }, /*192*/
585  { 70, 2, 3, 6, 19 }, /*193*/
586  { 70, 2, 3, 6, 19 }, /*194*/
587  { 70, 2, 3, 6, 19 }, /*195*/
588  { 70, 2, 3, 6, 19 }, /*196*/
589  { 70, 2, 3, 6, 19 }, /*197*/
590  { 70, 2, 3, 6, 19 }, /*198*/
591  { 70, 2, 3, 6, 19 }, /*199*/
592  { 70, 2, 3, 6, 19 }, /*200*/
593 };
594 
602 static int magic_from_difficulty(int difficulty) {
603  int percent, loop;
604 
605  difficulty--;
606  if (difficulty < 0)
607  difficulty = 0;
608 
609  if (difficulty >= DIFFLEVELS)
610  difficulty = DIFFLEVELS-1;
611 
612  percent = RANDOM()%100;
613 
614  for (loop = 0; loop < (MAXMAGIC+1); ++loop) {
615  percent -= difftomagic_list[difficulty][loop];
616  if (percent < 0)
617  break;
618  }
619  if (loop == (MAXMAGIC+1)) {
620  LOG(llevError, "Warning, table for difficulty %d bad.\n", difficulty);
621  loop = 0;
622  }
623  /* LOG(llevDebug, "Chose magic %d for difficulty %d\n", loop, difficulty);*/
624  return (RANDOM()%3) ? loop : -loop;
625 }
626 
642 void set_abs_magic(object *op, int magic) {
643  int32_t base_weight, base_speed;
644  if (!magic)
645  return;
646 
647  op->magic = magic;
648  if (op->arch) {
649  base_weight = op->arch->clone.weight;
650  base_speed = ARMOUR_SPEED(&op->arch->clone);
651  }
652  else {
653  base_weight = op->weight;
654  base_speed = ARMOUR_SPEED(op);
655  }
656  // Now we do the calculations
657  if (op->type == ARMOUR) {
659  ARMOUR_SPEED(op) = base_speed*(100+magic*settings.armor_speed_improvement)/100;
660  else
661  // This could have been done with a loop, but that seems to be less scalable.
662  // This will introduce less roundoff error than a loop, anyway
663  ARMOUR_SPEED(op) = (int32_t)(base_speed * pow(((float)(100+settings.armor_speed_improvement))/100, magic));
664  }
665  // Prepare for handling the weight. Sometimes cursed ones will have low weight like good ones.
666  if (magic < 0 && !(RANDOM()%3)) /* You can't just check the weight always */
667  magic = (-magic);
669  op->weight = (base_weight*(100-magic*settings.armor_weight_reduction))/100;
670  else
671  op->weight = (int32_t)(base_weight * pow(((float)(100-settings.armor_weight_reduction))/100, magic));
672 
673 }
674 
690 static void set_magic(int difficulty, object *op, int max_magic, int flags) {
691  int i;
692 
693  i = magic_from_difficulty(difficulty);
694  if ((flags&GT_ONLY_GOOD) && i < 0)
695  i = -i;
696  if (i > max_magic)
697  i = max_magic;
698  set_abs_magic(op, i);
699  if (i < 0)
700  SET_FLAG(op, FLAG_CURSED);
701 }
702 
719 static void set_ring_bonus(object *op, int bonus) {
720  int r = RANDOM()%(bonus > 0 ? 25 : 11);
721 
722  if (op->type == AMULET) {
723  if (!(RANDOM()%21))
724  r = 20+RANDOM()%2;
725  else {
726  if (RANDOM()&2)
727  r = 10;
728  else
729  r = 11+RANDOM()%9;
730  }
731  }
732 
733  switch (r) {
734  /* Redone by MSW 2000-11-26 to have much less code. Also,
735  * bonuses and penalties will stack and add to existing values.
736  * of the item.
737  */
738  case 0:
739  case 1:
740  case 2:
741  case 3:
742  case 4:
743  case 5:
744  case 6:
745  set_attr_value(&op->stats, r, (signed char)(bonus+get_attr_value(&op->stats, r)));
746  break;
747 
748  case 7:
749  op->stats.dam += bonus;
750  break;
751 
752  case 8:
753  op->stats.wc += bonus;
754  break;
755 
756  case 9:
757  op->stats.food += bonus; /* hunger/sustenance */
758  break;
759 
760  case 10:
761  op->stats.ac += bonus;
762  break;
763 
764  /* Item that gives protections/vulnerabilities */
765  case 11:
766  case 12:
767  case 13:
768  case 14:
769  case 15:
770  case 16:
771  case 17:
772  case 18:
773  case 19: {
774  int b = 5+FABS(bonus), val, resist = RANDOM()%num_resist_table;
775 
776  /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
777  val = 10+RANDOM()%b+RANDOM()%b+RANDOM()%b+RANDOM()%b;
778 
779  /* Cursed items need to have higher negative values to equal out with
780  * positive values for how protections work out. Put another
781  * little random element in since that they don't always end up with
782  * even values.
783  */
784  if (bonus < 0)
785  val = 2*-val-RANDOM()%b;
786  if (val > 35)
787  val = 35; /* Upper limit */
788  b = 0;
789  while (op->resist[resist_table[resist]] != 0 && b++ < 4) {
790  resist = RANDOM()%num_resist_table;
791  }
792  if (b == 4)
793  return; /* Not able to find a free resistance */
794  op->resist[resist_table[resist]] = val;
795  /* We should probably do something more clever here to adjust value
796  * based on how good a resistance we gave.
797  */
798  break;
799  }
800 
801  case 20:
802  if (op->type == AMULET) {
804  op->value *= 11;
805  } else {
806  op->stats.hp = 1; /* regenerate hit points */
807  op->value *= 4;
808  }
809  break;
810 
811  case 21:
812  if (op->type == AMULET) {
814  op->value *= 9;
815  } else {
816  op->stats.sp = 1; /* regenerate spell points */
817  op->value *= 3;
818  }
819  break;
820 
821  case 22:
822  op->stats.grace += bonus; /* regenerate grace */
823  op->value *= 5;
824  break;
825 
826  case 23:
827  op->stats.exp += bonus; /* Speed! */
828  op->value = (op->value*2)/3;
829  break;
830  }
831  if (bonus > 0)
832  op->value *= 2*bonus;
833  else
834  op->value = -(op->value*2*bonus)/3;
835 }
836 
847 static void trap_adjust(object *trap, int difficulty) {
848  int i;
849 
850  /* now we set the trap level to match the difficulty of the level
851  * the formula below will give a level from 1 to (2*difficulty) with
852  * a peak probability at difficulty
853  */
854 
855  trap->level = rndm(0, difficulty-1)+rndm(0, difficulty-1);
856  if (trap->level < 1)
857  trap->level = 1;
858 
859  /* set the hiddenness of the trap, similar formula to above */
860  trap->stats.Cha = rndm(0, 19)+rndm(0, difficulty-1)+rndm(0, difficulty-1);
861 
862  if (!trap->other_arch && !trap->inv) {
863  /* set the damage of the trap.
864  * we get 0-4 pts of damage per level of difficulty of the map in
865  * the trap
866  */
867 
868  trap->stats.dam = 0;
869  for (i = 0; i < difficulty; i++)
870  trap->stats.dam += rndm(0, 4);
871 
872  /* the poison trap special case */
873  if (trap->attacktype&AT_POISON) {
874  trap->stats.dam = rndm(0, difficulty-1);
875  if (trap->stats.dam < 1)
876  trap->stats.dam = 1;
877  }
878 
879  /* so we get an appropriate amnt of exp for AT_DEATH traps */
880  if (trap->attacktype&AT_DEATH)
881  trap->stats.dam = 127;
882  }
883 }
884 
885 #define DICE2 (dice2())
886 
890 bool chance(int a, int b) {
891  // Example: chance(2, 3). RANDOM%3 is 0, 1, or 2. 2/3 chance is the result < 2.
892  return RANDOM() % uint32_t(b) < uint32_t(a);
893 }
894 
895 static int dice2() {
896  return chance(2, 27) ? 2 : 1;
897 }
898 
899 #define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3)
900 
927 void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags) {
928  int was_magic = op->magic, num_enchantments = 0, save_item_power;
929 
930  if (!creator || creator->type == op->type)
931  creator = op; /* safety & to prevent polymorphed objects giving attributes */
932 
933  /* If we make an artifact, this information will be destroyed */
934  save_item_power = op->item_power;
935  op->item_power = 0;
936 
937  if (op->randomitems && op->type != SPELL) {
938  create_treasure(op->randomitems, op, flags, difficulty, 0);
939  if (!op->inv)
940  LOG(llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->name);
941  /* So the treasure doesn't get created again */
942  op->randomitems = NULL;
943  }
944 
945  if (difficulty < 1)
946  difficulty = 1;
947  if (!(flags&GT_MINIMAL)) {
948  if (op->arch == crown_arch) {
949  set_magic(difficulty > 25 ? 30 : difficulty+5, op, max_magic, flags);
950  num_enchantments = calc_item_power(op);
951  generate_artifact(op, difficulty);
952  } else {
953  if (!op->magic && max_magic)
954  set_magic(difficulty, op, max_magic, flags);
955  num_enchantments = calc_item_power(op);
956  if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT))
957  || op->type == ROD
958  || difficulty >= 999)
959  generate_artifact(op, difficulty);
960  }
961 
962  /* Object was made an artifact. Calculate its item_power rating.
963  * the item_power in the object is what the artifact adds.
964  */
965  if (op->title) {
966  /* if save_item_power is set, then most likely we started with an
967  * artifact and have added new abilities to it - this is rare, but
968  * but I have seen things like 'strange rings of fire'. So just
969  * figure out the power from the base power plus what this one adds.
970  * Note that since item_power is not quite linear, this actually
971  * ends up being somewhat of a bonus.
972  */
973  if (save_item_power)
974  op->item_power = save_item_power+get_power_from_ench(op->item_power);
975  else
976  op->item_power += get_power_from_ench(num_enchantments);
977  } else if (save_item_power) {
978  /* restore the item_power field to the object if we haven't changed
979  * it. we don't care about num_enchantments - that will basically
980  * just have calculated some value from the base attributes of the
981  * archetype.
982  */
983  op->item_power = save_item_power;
984  } else {
985  /* item_power was zero. This is suspicious, as it may be because it
986  * was never previously calculated. Let's compute a value and see if
987  * it is non-zero. If it indeed is, then assign it as the new
988  * item_power value.
989  * - gros, 21th of July 2006.
990  */
991  op->item_power = calc_item_power(op);
992  save_item_power = op->item_power; /* Just in case it would get used
993  * again below */
994  }
995  } else {
996  /* If flag is GT_MINIMAL, we want to restore item power */
997  op->item_power = save_item_power;
998  }
999 
1000  /* materialtype modifications. Note we allow this on artifacts. */
1001  set_materialname(op);
1002 
1003  if (flags&GT_MINIMAL) {
1004  if (op->type == POTION)
1005  /* Handle healing and magic power potions */
1006  if (op->stats.sp && !op->randomitems) {
1007  object *tmp;
1008  if (spell_mapping[op->stats.sp]) {
1009  tmp = create_archetype(spell_mapping[op->stats.sp]);
1010  object_insert_in_ob(tmp, op);
1011  }
1012  op->stats.sp = 0;
1013  }
1014  } else if (!op->title) { /* Only modify object if not special */
1015  switch (op->type) {
1016  case WEAPON:
1017  case ARMOUR:
1018  case SHIELD:
1019  case HELMET:
1020  case CLOAK:
1021  if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4))
1022  set_ring_bonus(op, -DICE2);
1023  break;
1024 
1025  case BRACERS:
1026  if (!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED) ? 5 : 20))) {
1028  if (!QUERY_FLAG(op, FLAG_CURSED))
1029  op->value *= 3;
1030  }
1031  break;
1032 
1033  case POTION: {
1034  int too_many_tries = 0, is_special = 0;
1035 
1036  /* Handle healing and magic power potions */
1037  if (op->stats.sp && !op->randomitems) {
1038  object *tmp;
1039 
1040  tmp = create_archetype(spell_mapping[op->stats.sp]);
1041  object_insert_in_ob(tmp, op);
1042  op->stats.sp = 0;
1043  }
1044 
1045  while (!(is_special = special_potion(op)) && !op->inv) {
1046  generate_artifact(op, difficulty);
1047  if (too_many_tries++ > 10)
1048  break;
1049  }
1050  /* don't want to change value for healing/magic power potions,
1051  * since the value set on those is already correct.
1052  */
1053  if (op->inv && op->randomitems) {
1054  /* value multiplier is same as for scrolls */
1055  op->value = (op->value*op->inv->value);
1056  op->level = op->inv->level/2+RANDOM()%difficulty+RANDOM()%difficulty;
1057  } else {
1058  FREE_AND_COPY(op->name, "potion");
1059  FREE_AND_COPY(op->name_pl, "potions");
1060  }
1061  if (!(flags&GT_ONLY_GOOD) && RANDOM()%2)
1062  SET_FLAG(op, FLAG_CURSED);
1063  break;
1064  }
1065 
1066  case AMULET:
1067  if (op->arch == amulet_arch)
1068  op->value *= 5; /* Since it's not just decoration */
1069  /* fall through */
1070  case RING:
1071  if (op->arch == NULL) {
1072  object_remove(op);
1074  op = NULL;
1075  return;
1076  }
1077  if (op->arch != ring_arch && op->arch != amulet_arch)
1078  /* It's a special artifact!*/
1079  break;
1080 
1081  if (GET_ANIM_ID(op))
1082  SET_ANIMATION(op, RANDOM()%((int)NUM_ANIMATIONS(op)));
1083  if (!(flags&GT_ONLY_GOOD) && !(RANDOM()%3))
1084  SET_FLAG(op, FLAG_CURSED);
1086  if (op->type != RING) /* Amulets have only one ability */
1087  break;
1088  if (!(RANDOM()%4)) {
1089  int d = (RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1090  if (d > 0)
1091  op->value *= 3;
1092  set_ring_bonus(op, d);
1093  if (!(RANDOM()%4)) {
1094  int d = (RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1095  if (d > 0)
1096  op->value *= 5;
1097  set_ring_bonus(op, d);
1098  }
1099  }
1100  break;
1101 
1102  case BOOK:
1103  /* Is it an empty book?, if yes lets make a special
1104  * msg for it, and tailor its properties based on the
1105  * creator and/or map level we found it on.
1106  */
1107  if (!op->msg && RANDOM()%10) {
1108  /* set the book level properly */
1109  if (creator->level == 0 || QUERY_FLAG(creator, FLAG_ALIVE)) {
1110  if (op->map && op->map->difficulty)
1111  op->level = RANDOM()%(op->map->difficulty)+RANDOM()%10+1;
1112  else
1113  op->level = RANDOM()%20+1;
1114  } else
1115  op->level = RANDOM()%creator->level;
1116 
1117  tailor_readable_ob(op, creator->stats.sp);
1118  /* books w/ info are worth more! */
1119  if (op->msg != NULL)
1120  op->value *= ((op->level > 10 ? op->level : (op->level+1)/2)*((strlen(op->msg)/250)+1));
1121  /* creator related stuff */
1122 
1123  if (creator->slaying && !op->slaying) /* for check_inv floors */
1124  op->slaying = add_string(creator->slaying);
1125 
1126  /* add exp so reading it gives xp (once)*/
1127  op->stats.exp = op->value > 10000 ? op->value/5 : op->value/10;
1128  }
1129  /* for library, chained books. Note that some monsters have
1130  * no_pick set - we don't want to set no pick in that case. */
1131  if (QUERY_FLAG(creator, FLAG_NO_PICK)
1132  && !QUERY_FLAG(creator, FLAG_MONSTER)
1133  && creator->type != SHOP_MAT) // shop readables need to be pickable
1134  SET_FLAG(op, FLAG_NO_PICK);
1135  break;
1136 
1137  case SPELLBOOK:
1138  if (!op->inv) {
1139  LOG(llevError, "Generated a spellbook without a spell\n");
1140  break;
1141  }
1142  op->value = op->value*op->inv->value;
1143  /* add exp so learning gives xp */
1144  op->level = op->inv->level;
1145  op->stats.exp = op->value;
1146  /* some more fun */
1147  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 5) {
1148  if (rndm(1, 6) <= 1)
1149  SET_FLAG(op, FLAG_DAMNED);
1150  else
1151  SET_FLAG(op, FLAG_CURSED);
1152  } else if (rndm(1, 100) <= 1) {
1153  SET_FLAG(op, FLAG_BLESSED);
1154  }
1155  break;
1156 
1157  case WAND:
1158  if (!op->inv) {
1159  LOG(llevError, "Generated a wand without a spell\n");
1160  break;
1161  }
1162  /* nrof in the treasure list is number of charges,
1163  * not number of wands. So copy that into food (charges),
1164  * and reset nrof.
1165  */
1166  op->stats.food = op->inv->nrof;
1167  op->nrof = 1;
1168  /* If the spell changes by level, choose a random level
1169  * for it, and adjust price. If the spell doesn't
1170  * change by level, just set the wand to the level of
1171  * the spell, and value calculation is simpler.
1172  */
1173  if (op->inv->duration_modifier
1174  || op->inv->dam_modifier
1175  || op->inv->range_modifier) {
1176  op->level = level_for_item(op, difficulty);
1177  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1178  } else {
1179  op->level = op->inv->level;
1180  op->value = op->value*op->inv->value;
1181  }
1182  break;
1183 
1184  case ROD:
1185  op->level = level_for_item(op, difficulty);
1186  rod_adjust(op);
1187  break;
1188 
1189  case SCROLL:
1190  if (!op->inv) {
1191  // Somehow generated a scroll without a spell...
1192  LOG(llevError, "Generated a scroll without a spell\n");
1193  break;
1194  }
1195  op->level = level_for_item(op, difficulty);
1196  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1197  /* add exp so reading them properly gives xp */
1198  op->stats.exp = op->value/5;
1199  op->nrof = op->inv->nrof;
1200  /* some more fun */
1201  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 20) {
1202  if (rndm(1, 6) <= 1)
1203  SET_FLAG(op, FLAG_DAMNED);
1204  else
1205  SET_FLAG(op, FLAG_CURSED);
1206  } else if (rndm(1, 100) <= 2) {
1207  SET_FLAG(op, FLAG_BLESSED);
1208  }
1209  break;
1210 
1211  case RUNE:
1212  trap_adjust(op, difficulty);
1213  break;
1214 
1215  case TRAP:
1216  trap_adjust(op, difficulty);
1217  break;
1218  } /* switch type */
1219  }
1220  if (flags&GT_STARTEQUIP) {
1221  if (op->nrof < 2
1222  && op->type != CONTAINER
1223  && op->type != MONEY
1224  && !QUERY_FLAG(op, FLAG_IS_THROWN)) {
1226  SET_FLAG(op, FLAG_INV_LOCKED); // make it harder to accidentally drop
1227  }
1228  else if (op->type != MONEY)
1229  op->value = 0;
1230  }
1231 
1232  if (!(flags&GT_ENVIRONMENT))
1233  fix_flesh_item(op, creator);
1234 }
1235 
1239 static void dump_monster_treasure_rec(const char *name, treasure *t, int depth) {
1240  treasurelist *tl;
1241  int i;
1242 
1243  if (depth > 100)
1244  return;
1245 
1246  while (t != NULL) {
1247  if (t->name != NULL) {
1248  for (i = 0; i < depth; i++)
1249  fprintf(logfile, " ");
1250  fprintf(logfile, "{ (list: %s)\n", t->name);
1251  tl = find_treasurelist(t->name);
1252  dump_monster_treasure_rec(name, tl->items, depth+2);
1253  for (i = 0; i < depth; i++)
1254  fprintf(logfile, " ");
1255  fprintf(logfile, "} (end of list: %s)\n", t->name);
1256  } else {
1257  for (i = 0; i < depth; i++)
1258  fprintf(logfile, " ");
1259  if (t->item->clone.type == FLESH)
1260  fprintf(logfile, "%s's %s\n", name, t->item->clone.name);
1261  else
1262  fprintf(logfile, "%s\n", t->item->clone.name);
1263  }
1264  if (t->next_yes != NULL) {
1265  for (i = 0; i < depth; i++)
1266  fprintf(logfile, " ");
1267  fprintf(logfile, " (if yes)\n");
1268  dump_monster_treasure_rec(name, t->next_yes, depth+1);
1269  }
1270  if (t->next_no != NULL) {
1271  for (i = 0; i < depth; i++)
1272  fprintf(logfile, " ");
1273  fprintf(logfile, " (if no)\n");
1274  dump_monster_treasure_rec(name, t->next_no, depth+1);
1275  }
1276  t = t->next;
1277  }
1278 }
1279 
1284 void dump_monster_treasure(const char *name) {
1285  int found;
1286 
1287  found = 0;
1288  fprintf(logfile, "\n");
1289  getManager()->archetypes()->each([&] (const auto at) {
1290  if (!strcasecmp(at->clone.name, name) && at->clone.title == NULL) {
1291  fprintf(logfile, "treasures for %s (arch: %s)\n", at->clone.name, at->name);
1292  if (at->clone.randomitems != NULL)
1293  dump_monster_treasure_rec(at->clone.name, at->clone.randomitems->items, 1);
1294  else
1295  fprintf(logfile, "(nothing)\n");
1296  fprintf(logfile, "\n");
1297  found++;
1298  }
1299  });
1300 
1301  if (found == 0)
1302  fprintf(logfile, "No objects have the name %s!\n\n", name);
1303 }
1304 
1312 static void fix_flesh_item(object *item, const object *donor) {
1313  char tmpbuf[MAX_BUF];
1314  int i;
1315 
1316  if (item->type == FLESH && donor && QUERY_FLAG(donor, FLAG_MONSTER)) {
1317  /* change the name */
1318  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name);
1319  FREE_AND_COPY(item->name, tmpbuf);
1320  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name_pl);
1321  FREE_AND_COPY(item->name_pl, tmpbuf);
1322 
1323  /* store original arch in other_arch */
1324  if (!item->other_arch) {
1325  if (!donor->arch->reference_count) {
1326  item->other_arch = donor->arch;
1327  } else {
1328  /* If dealing with custom monsters, other_arch still needs to
1329  * point back to the original. Otherwise what happens
1330  * is that other_arch points at the custom archetype, but
1331  * that can be freed. Reference count doesn't work because
1332  * the loader will not be able to resolve the other_arch at
1333  * load time (server may has restarted, etc.)
1334  */
1335  archetype *original = find_archetype(donor->arch->name);
1336 
1337  if (original)
1338  item->other_arch = original;
1339  else {
1340  LOG(llevError, "could not find original archetype %s for custom monster!\n", donor->arch->name);
1341  abort();
1342  }
1343  }
1344  }
1345 
1346  /* weight is FLESH weight/100 * donor */
1347  if ((item->weight = (signed long)(((double)item->weight/(double)100.0)*(double)donor->weight)) == 0)
1348  item->weight = 1;
1349 
1350  /* value is multiplied by level of donor */
1351  item->value *= isqrt(donor->level*2);
1352 
1353  /* food value */
1354  item->stats.food += (donor->stats.hp/100)+donor->stats.Con;
1355 
1356  /* flesh items inherit some abilities of donor, but not full effect. */
1357  for (i = 0; i < NROFATTACKS; i++)
1358  item->resist[i] = donor->resist[i]/2;
1359 
1360  /* item inherits donor's level and exp (important for dragons) */
1361  item->level = donor->level;
1362  item->stats.exp = donor->stats.exp;
1363 
1364  /* if donor has some attacktypes, the flesh is poisonous */
1365  if (donor->attacktype&AT_POISON)
1366  item->type = POISON;
1367  if (donor->attacktype&AT_ACID)
1368  item->stats.hp = -1*item->stats.food;
1369  SET_FLAG(item, FLAG_NO_STEAL);
1370 
1371  /* attempt to change the face - will take a face named "donor's arch"_"item's face". We ignore the animation for now */
1372  if (item->face != NULL) {
1373  snprintf(tmpbuf, sizeof(tmpbuf), "%s_%s", donor->arch->name, item->face->name);
1374  item->face = try_find_face(tmpbuf, item->face);
1375  }
1376  }
1377 }
1378 
1387 static int special_potion(object *op) {
1388  int i;
1389 
1390  if (op->attacktype)
1391  return 1;
1392 
1393  if (op->stats.Str
1394  || op->stats.Dex
1395  || op->stats.Con
1396  || op->stats.Pow
1397  || op->stats.Wis
1398  || op->stats.Int
1399  || op->stats.Cha)
1400  return 1;
1401 
1402  for (i = 0; i < NROFATTACKS; i++)
1403  if (op->resist[i])
1404  return 1;
1405 
1406  return 0;
1407 }
1408 
1421  treasure *t = (treasure *)calloc(1, sizeof(treasure));
1422  if (t == NULL)
1424  t->item = NULL;
1425  t->name = NULL;
1426  t->next = NULL;
1427  t->next_yes = NULL;
1428  t->next_no = NULL;
1429  t->chance = 100;
1430  t->magic = 0;
1431  t->nrof = 0;
1432  return t;
1433 }
1434 
1442  if (t->name)
1443  free_string(t->name);
1444  if (t->artifact)
1445  free_string(t->artifact);
1446  if (t->next)
1447  treasure_free(t->next);
1448  if (t->next_yes)
1449  treasure_free(t->next_yes);
1450  if (t->next_no)
1451  treasure_free(t->next_no);
1452  free(t);
1453 }
1454 
1455 
1462 treasure *treasure_insert(treasurelist *list, int position) {
1463  treasure *added = get_empty_treasure();
1464  if (list->items == NULL || position <= 0) {
1465  added->next = list->items;
1466  list->items = added;
1467  return added;
1468  }
1469  treasure *prev = list->items;
1470  position--;
1471  while (position > 0 && prev->next) {
1472  position--;
1473  prev = prev->next;
1474  }
1475  added->next = prev->next;
1476  prev->next = added;
1477  return added;
1478 }
1479 
1485 void treasure_remove_item(treasurelist *list, int position) {
1486  if (list->items == 0 || position < 0) {
1487  return;
1488  }
1489  if (position == 0) {
1490  treasure *next = list->items->next;
1491  list->items->next = NULL;
1492  treasure_free(list->items);
1493  list->items = next;
1494  return;
1495  }
1496  position--;
1497  treasure *prev = list->items;
1498  while (prev && position > 0) {
1499  position--;
1500  prev = prev->next;
1501  }
1502  if (!prev) {
1503  return;
1504  }
1505  treasure *next = prev->next->next;
1506  prev->next->next = NULL;
1507  treasure_free(prev->next);
1508  prev->next = next;
1509 }
#define ATNR_FEAR
Definition: attack.h:61
Error, serious thing.
Definition: logger.h:11
static void set_ring_bonus(object *op, int bonus)
Randomly adds one magical ability to the given object.
Definition: treasure.cpp:719
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:305
#define ATNR_ELECTRICITY
Definition: attack.h:50
void treasure_remove_item(treasurelist *list, int position)
Remove the treasure at the specified position from the list.
Definition: treasure.cpp:1485
See Ring.
Definition: object.h:190
int8_t item_power
Power rating of the object.
Definition: object.h:372
int calc_item_power(const object *op)
This takes an object &#39;op&#39; and figures out what its item_power rating should be.
Definition: item.cpp:318
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
#define ATNR_SLOW
Definition: attack.h:58
static const int difftomagic_list[DIFFLEVELS][MAXMAGIC+1]
Based upon the specified difficulty and upon the difftomagic_list array, a random magical bonus is re...
Definition: treasure.cpp:389
const char *const spell_mapping[SPELL_MAPPINGS]
This table is only necessary to convert objects that existed before the spell object conversion to th...
Definition: object.cpp:74
FILE * logfile
Used by server/daemon.c.
Definition: init.cpp:114
Unused?
Definition: treasure.h:32
const char * name
If != NULL, copy this over the original arch name.
Definition: treasure.h:52
static int resist_table[]
Resistances which can show up on rings and amulets.
Definition: treasure.cpp:39
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
See Bracers.
Definition: object.h:222
#define MAXMAGIC
Maximum magic for difficulty/magic mapping.
Definition: treasure.h:13
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
int rndm(int min, int max)
Returns a number between min and max.
Definition: utils.cpp:162
See Scroll.
Definition: object.h:226
#define ATNR_FIRE
Definition: attack.h:49
#define ATNR_DISEASE
Definition: attack.h:72
void tailor_readable_ob(object *book, int msg_type)
The main routine.
Definition: readable.cpp:1899
See Cloak.
Definition: object.h:209
int16_t grace
Grace.
Definition: living.h:44
#define ATNR_ACID
Definition: attack.h:53
archetype * find_archetype(const char *name)
Definition: assets.cpp:270
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.cpp:1818
void set_materialname(object *op)
Set the material name and type for an item, if not set.
Definition: utils.cpp:297
int level
Definition: readable.cpp:1561
#define ATNR_CONFUSION
Definition: attack.h:52
sstring name
If non null, name of list to use instead.
Definition: treasure.h:66
#define SET_ANIMATION(ob, newanim)
Definition: global.h:164
See Spellbook.
Definition: object.h:208
See Money.
Definition: object.h:142
sstring slaying
Which race to do double damage to.
Definition: object.h:327
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
int32_t value
How much money it is worth (or contains)
Definition: object.h:360
int8_t list_magic_adjustment
Adjust difficulty when generating the list pointed by name, ignored if list_magic_value is non zero...
Definition: treasure.h:67
See Rune.
Definition: object.h:245
See Weapon.
Definition: object.h:124
See Helmet.
Definition: object.h:141
void generate_artifact(object *op, int difficulty)
Decides randomly which artifact the object should be turned into.
Definition: artifact.cpp:177
See Rod.
Definition: object.h:114
int16_t y
Position in the map for this object.
Definition: object.h:335
int8_t magic
Any magical bonuses to this item.
Definition: object.h:358
Do minimal adjustments, don&#39;t make artifacts, and so on.
Definition: treasure.h:36
#define FLAG_BLESSED
Item has a blessing, opposite of cursed/damned.
Definition: define.h:365
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:547
int get_power_from_ench(int ench)
Definition: item.cpp:213
See Amulet.
Definition: object.h:144
#define ATNR_PARALYZE
Definition: attack.h:59
#define MAX(x, y)
Definition: compat.h:24
int16_t x
Definition: object.h:335
animal &#39;body parts&#39; -b.t.
Definition: object.h:192
Global type definitions and header inclusions.
int8_t Con
Use
Definition: living.h:36
static archetype * crown_arch
Definition: treasure.cpp:50
See Wand & Staff.
Definition: object.h:225
static void fix_flesh_item(object *item, const object *donor)
Objects of type FLESH are similar to type FOOD, except they inherit properties (name, food value, etc).
Definition: treasure.cpp:1312
void set_attr_value(living *stats, int attr, int8_t value)
Sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on what attr is (STR to POW)...
Definition: living.cpp:218
treasure * treasure_insert(treasurelist *list, int position)
Insert a new treasure in the treasure list, at a specific position in the children list...
Definition: treasure.cpp:1462
int32_t weight
Attributes of the object.
Definition: object.h:375
bool chance(int a, int b)
Return true with a probability of a/b.
Definition: treasure.cpp:890
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.cpp:1284
#define NROFATTACKS
Definition: attack.h:15
AssetsManager * getManager()
Definition: assets.cpp:309
#define ATNR_TURN_UNDEAD
Definition: attack.h:60
const Face * try_find_face(const char *name, const Face *error)
Definition: assets.cpp:290
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.cpp:294
See Trap.
Definition: object.h:246
int16_t level
Level of creature or object.
Definition: object.h:361
int16_t sp
Spell points.
Definition: living.h:42
#define ATNR_DEATH
Definition: attack.h:64
static archetype * ring_arch
Arches for rings, amulets and crowns.
Definition: treasure.cpp:50
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.cpp:1577
int legal_artifact_combination(const object *op, const artifact *art)
Checks if op can be combined with art.
Definition: artifact.cpp:252
#define FREE_OBJ_FREE_INVENTORY
Free inventory objects; if not set, drop inventory.
Definition: object.h:546
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:217
int armor_speed_improvement
Speed improvement.
Definition: global.h:309
static void create_one_treasure(treasurelist *tl, object *op, int flag, int difficulty, int tries)
Creates one treasure from the list.
Definition: treasure.cpp:232
int16_t resist[NROFATTACKS]
Resistance adjustments for attacks.
Definition: object.h:351
#define FLAG_REFL_SPELL
Spells (some) will reflect from object.
Definition: define.h:262
See Book.
Definition: object.h:119
#define ATNR_COLD
Definition: attack.h:51
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.cpp:287
#define FLAG_OBJ_ORIGINAL
NEVER SET THIS.
Definition: define.h:352
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:483
#define DIFFLEVELS
Maximum difficulty for difficulty/magic mapping.
Definition: treasure.h:16
sstring name
More definite name, like "generate_kobold".
Definition: object.h:484
#define FLAG_NO_STEAL
Item can&#39;t be stolen.
Definition: define.h:330
Defines for loader.l / loader.c.
int8_t Dex
Use
Definition: living.h:36
Defines and variables used by the artifact generation routines.
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
Definition: arch.cpp:227
object * create_archetype(const char *name)
Finds which archetype matches the given name, and returns a new object containing a copy of the arche...
Definition: arch.cpp:276
#define SET_FLAG(xyz, p)
Definition: define.h:384
#define CHANCE_FOR_ARTIFACT
Chance an item becomes an artifact if not magic is 1 in this value.
Definition: treasure.h:10
#define MAX_SPELLITEM_LEVEL
Highest level of rods/staves/scrolls to generate.
Definition: treasure.h:19
#define QUERY_FLAG(xyz, p)
Definition: define.h:386
const artifact * find_artifact(const object *op, const char *name)
Searches and returns a specific artifact compatible with an object, NULL if not found.
Definition: artifact.cpp:585
int8_t Wis
Use
Definition: living.h:36
void give_artifact_abilities(object *op, const object *artifact)
Fixes the given object, giving it the abilities and titles it should have due to the second artifact-...
Definition: artifact.cpp:230
int strcasecmp(const char *s1, const char *s2)
uint8_t chance
Percent chance for this item.
Definition: treasure.h:73
static void set_magic(int difficulty, object *op, int max_magic, int flags)
Sets a random magical bonus in the given object based upon the given difficulty, and the given max po...
Definition: treasure.cpp:690
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.cpp:1545
uint8_t armor_weight_linear
If 1, weight reduction is linear, else exponantiel.
Definition: global.h:308
sstring msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:330
void set_abs_magic(object *op, int magic)
Sets magical bonus in an object, and recalculates the effect on the armour variable, and the effect on speed of armour.
Definition: treasure.cpp:642
static void dump_monster_treasure_rec(const char *name, treasure *t, int depth)
For debugging purposes.
Definition: treasure.cpp:1239
const char * title
If != NULL, copy this over the original arch title.
Definition: treasure.h:53
#define ATNR_BLIND
Definition: attack.h:69
uint8_t range_modifier
How going up in level affects range.
Definition: object.h:418
#define ARMOUR_SPEED(xyz)
Definition: define.h:466
#define DICE2
Definition: treasure.cpp:885
Archetypes * archetypes()
Get archetypes.
Definition: AssetsManager.h:44
#define INS_NO_WALK_ON
Don&#39;t call check_walk_on against the originator.
Definition: object.h:584
uint8_t armor_speed_linear
If 1, speed improvement is linear, else exponantiel.
Definition: global.h:310
const Face * face
Face with colors.
Definition: object.h:341
uint64_t shopmin
Minimum price a shop will trade for.
Definition: map.h:354
uint8_t dam_modifier
How going up in level affects damage.
Definition: object.h:419
See Potion.
Definition: object.h:116
struct Settings settings
Global settings.
Definition: init.cpp:139
int16_t total_chance
If non-zero, only 1 item on this list should be generated.
Definition: treasure.h:87
See Shop Mat.
Definition: object.h:189
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it...
Definition: object.cpp:1258
static int level_for_item(const object *op, int difficulty)
Calculate the appropriate level for wands staves and scrolls.
Definition: treasure.cpp:347
int16_t dam
How much damage this object does when hitting.
Definition: living.h:46
See Spell.
Definition: object.h:219
treasure * next_no
If this item was not generated, then continue here.
Definition: treasure.h:71
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:590
int isqrt(int n)
Compute the square root.
Definition: utils.cpp:562
living stats
Str, Con, Dex, etc.
Definition: object.h:378
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
#define ATNR_POISON
Definition: attack.h:57
int16_t invisible
How much longer the object will be invis.
Definition: object.h:370
uint64_t price_base(const object *obj)
Price an item based on its value or archetype value, type, identification/BUC status, and other heuristics.
Definition: item.cpp:1507
static bool do_single_item(treasure *t, object *op, int flag, int difficulty)
Creates the item for a treasure.
Definition: treasure.cpp:139
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
#define num_resist_table
Number of items in resist_table.
Definition: treasure.cpp:53
See Container.
Definition: object.h:236
#define FLAG_IS_THROWN
Object is designed to be thrown.
Definition: define.h:236
static const flag_definition flags[]
Flag mapping.
treasurelist represents one logical group of items to be generated together.
Definition: treasure.h:85
treasure * next_yes
If this item was generated, use this link instead of ->next.
Definition: treasure.h:70
#define FLAG_CURSED
The object is cursed.
Definition: define.h:304
struct archetype * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:425
See Poison Food.
Definition: object.h:118
See Shield.
Definition: object.h:140
struct treasurelist * randomitems
Items to be generated.
Definition: object.h:395
#define AT_POISON
Some damage each turn thereafter (1024)
Definition: attack.h:88
sstring name_pl
The plural name of the object.
Definition: object.h:323
sstring artifact
If not null, the name of the artifact to apply to item.
Definition: treasure.h:65
#define INS_NO_MERGE
Don&#39;t try to merge with other items.
Definition: object.h:582
#define RANDOM()
Definition: define.h:667
int armor_weight_reduction
Weight reduction per enchantment.
Definition: global.h:307
#define FREE_AND_COPY(sv, nv)
Release the shared string if not NULL, and make it a reference to nv.
Definition: global.h:206
treasure * next
Next treasure-item in a linked list.
Definition: treasure.h:69
#define NUM_ANIMATIONS(ob)
Definition: global.h:173
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
Definition: treasure.cpp:319
struct _change_arch change_arch
Override default arch values if set in treasure list.
Definition: treasure.h:72
#define ATNR_DRAIN
Definition: attack.h:54
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
fix_generated_item(): This is called after an item is generated, in order to set it up right...
Definition: treasure.cpp:927
sstring name
The name of the object, obviously...
Definition: object.h:319
int8_t get_attr_value(const living *stats, int attr)
Gets the value of a stat.
Definition: living.cpp:313
See Shop Floor.
Definition: object.h:188
#define ATNR_GHOSTHIT
Definition: attack.h:56
sstring title
Of foo, etc.
Definition: object.h:325
Only for debugging purposes.
Definition: logger.h:13
uint32_t nrof
Number of objects.
Definition: object.h:342
sstring name
Usually monster-name/combination.
Definition: treasure.h:86
int8_t Cha
Use
Definition: living.h:36
treasure * items
Items in this list, linked.
Definition: treasure.h:92
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
uint8_t list_magic_value
Set difficulty when generating the list pointed by name.
Definition: treasure.h:68
int8_t ac
Armor Class, lower AC increases probability of not getting hit.
Definition: living.h:38
uint16_t nrof
Random 1 to nrof items are generated.
Definition: treasure.h:79
int reference_count
How many times this temporary archetype is used.
Definition: object.h:490
#define ATNR_MAGIC
Definition: attack.h:48
int8_t Pow
Use
Definition: living.h:36
treasure * get_empty_treasure(void)
Allocate and return the pointer to an empty treasure structure.
Definition: treasure.cpp:1420
treasurelist * find_treasurelist(const char *name)
Search for the given treasurelist by name.
Definition: assets.cpp:253
static int special_potion(object *op)
Check if object is a special potion.
Definition: treasure.cpp:1387
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
#define ATNR_HOLYWORD
Definition: attack.h:68
#define FLAG_STARTEQUIP
Object was given to player at start.
Definition: define.h:255
treasure is one element in a linked list, which together consist of a complete treasure-list.
Definition: treasure.h:63
static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries)
Creates all the treasures.
Definition: treasure.cpp:193
#define GET_ANIM_ID(ob)
Definition: global.h:167
static int magic_from_difficulty(int difficulty)
This is used when determining the magical bonus created on specific maps.
Definition: treasure.cpp:602
Don&#39;t generate bad/cursed items.
Definition: treasure.h:34
int64_t exp
Experience.
Definition: living.h:47
uint32_t attacktype
Bitmask of attacks this object does.
Definition: object.h:352
static void put_treasure(object *op, object *creator, int flags)
Inserts generated treasure where it should go.
Definition: treasure.cpp:82
const char * slaying
If != NULL, copy this over the original arch slaying.
Definition: treasure.h:54
#define FLAG_MONSTER
Will attack players.
Definition: define.h:232
static archetype * amulet_arch
Definition: treasure.cpp:50
C function wrappers to interact with assets.
uint8_t magic
Max magic bonus to item If the entry is a list transition, &#39;magic&#39; contains the difficulty required t...
Definition: treasure.h:74
static void change_treasure(treasure *t, object *op)
if there are change_xxx commands in the treasure, we include the changes in the generated object ...
Definition: treasure.cpp:105
int32_t food
How much food in stomach.
Definition: living.h:48
#define ATNR_DEPLETE
Definition: attack.h:63
struct archetype * item
Which item this link can be.
Definition: treasure.h:64
void rod_adjust(object *rod)
Adjusts rod attributes.
Definition: main.cpp:390
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:338
void treasure_free(treasure *t)
Frees a treasure, including its yes, no and next items.
Definition: treasure.cpp:1441
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.cpp:2842
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.cpp:2085
int8_t Int
Use
Definition: living.h:36
int8_t wc
Weapon Class, lower WC increases probability of hitting.
Definition: living.h:37
static void trap_adjust(object *trap, int difficulty)
Adjust trap difficulty to the map.
Definition: treasure.cpp:847
static int dice2()
Definition: treasure.cpp:895
#define FLAG_NO_PICK
Object can&#39;t be picked up.
Definition: define.h:226
void init_archetype_pointers(void)
Initialize global archtype pointers:
Definition: treasure.cpp:62
See Breastplate Armor.
Definition: object.h:125
#define FLAG_REFL_MISSILE
Arrows will reflect from object.
Definition: define.h:260
#define AT_ACID
Random equipped item might corrode when hit (64)
Definition: attack.h:84
#define FLAG_INV_LOCKED
Item will not be dropped from inventory.
Definition: define.h:317
This is one artifact, ie one special item.
Definition: artifact.h:14
#define AT_DEATH
Chance of instant death, otherwise nothing (131072) peterm@soda.berkeley.edu.
Definition: attack.h:95
sstring name
Face name, as used by archetypes and such.
Definition: face.h:19
object clone
An object from which to do object_copy()
Definition: object.h:487
uint8_t duration_modifier
how level modifies duration
Definition: object.h:416
#define ATNR_LIFE_STEALING
Definition: attack.h:71
int8_t Str
Use
Definition: living.h:36
#define ATNR_PHYSICAL
Definition: attack.h:47
object * item
Special values of the artifact.
Definition: artifact.h:15
int16_t hp
Hit Points.
Definition: living.h:40
Generated items have the FLAG_STARTEQUIP.
Definition: treasure.h:33
void each(std::function< void(T *)> op)
Apply a function to each asset.