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