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) {
90  object_insert_in_map_at(op, creator->map, op, INS_NO_MERGE|INS_NO_WALK_ON, creator->x, creator->y);
91  } else
92  object_insert_in_ob(op, creator);
93 }
94 
105 static void change_treasure(treasure *t, object *op) {
106  /* CMD: change_name xxxx */
107  if (t->change_arch.name) {
108  FREE_AND_COPY(op->name, t->change_arch.name);
109  /* not great, but better than something that is completely wrong */
110  FREE_AND_COPY(op->name_pl, t->change_arch.name);
111  }
112 
113  if (t->change_arch.title) {
114  if (op->title)
115  free_string(op->title);
116  op->title = add_string(t->change_arch.title);
117  }
118 
119  if (t->change_arch.slaying) {
120  if (op->slaying)
121  free_string(op->slaying);
122  op->slaying = add_string(t->change_arch.slaying);
123  }
124 }
125 
139 static 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 
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 
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 }
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:61
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:690
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:545
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:642
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:1239
INS_NO_WALK_ON
#define INS_NO_WALK_ON
Don't call check_walk_on against the originator.
Definition: object.h:582
AT_POISON
#define AT_POISON
Definition: attack.h:86
BRACERS
@ BRACERS
Definition: object.h:222
find_artifact
const artifact * find_artifact(const object *op, const char *name)
Searches and returns a specific artifact compatible with an object, NULL if not found.
Definition: artifact.cpp:589
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
DICE2
#define DICE2
Definition: treasure.cpp:885
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:333
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:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
Settings::armor_speed_linear
uint8_t armor_speed_linear
If 1, speed improvement is linear, else exponantiel.
Definition: global.h:310
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:55
FLAG_STARTEQUIP
#define FLAG_STARTEQUIP
Object was given to player at start.
Definition: define.h:268
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:226
mapstruct::shopmin
uint64_t shopmin
Minimum price a shop will trade for.
Definition: map.h:349
FLAG_REFL_MISSILE
#define FLAG_REFL_MISSILE
Arrows will reflect from object.
Definition: define.h:273
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:347
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:36435
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
FLAG_OBJ_ORIGINAL
#define FLAG_OBJ_ORIGINAL
NEVER SET THIS.
Definition: define.h:357
TRAP
@ TRAP
Definition: object.h:246
object::x
int16_t x
Definition: object.h:335
ARMOUR
@ ARMOUR
Definition: object.h:125
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:249
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
Definition: treasure.cpp:319
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:164
ATNR_SLOW
#define ATNR_SLOW
Definition: attack.h:60
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:139
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:927
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
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:297
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:74
FLAG_BLESSED
#define FLAG_BLESSED
Item has a blessing, opposite of cursed/damned.
Definition: define.h:369
get_empty_treasure
treasure * get_empty_treasure(void)
Allocate and return the pointer to an empty treasure structure.
Definition: treasure.cpp:1420
rod_adjust
void rod_adjust(object *rod)
Adjusts rod attributes.
Definition: main.cpp:390
ATNR_PHYSICAL
#define ATNR_PHYSICAL
Definition: attack.h:49
ARMOUR_SPEED
#define ARMOUR_SPEED(xyz)
Definition: define.h:460
special_potion
static int special_potion(object *op)
Check if object is a special potion.
Definition: treasure.cpp:1387
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
create_all_treasures
static void create_all_treasures(treasure *t, object *op, int flag, int difficulty, int tries)
Creates all the treasures.
Definition: treasure.cpp:193
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:62
object::title
sstring title
Of foo, etc.
Definition: object.h:325
FLAG_INV_LOCKED
#define FLAG_INV_LOCKED
Item will not be dropped from inventory.
Definition: define.h:329
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:305
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
AT_DEATH
#define AT_DEATH
Definition: attack.h:93
object::resist
int16_t resist[NROFATTACKS]
Resistance adjustments for attacks.
Definition: object.h:351
FLAG_NO_PICK
#define FLAG_NO_PICK
Object can't be picked up.
Definition: define.h:239
ATNR_CONFUSION
#define ATNR_CONFUSION
Definition: attack.h:54
ATNR_HOLYWORD
#define ATNR_HOLYWORD
Definition: attack.h:70
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:105
FLAG_ALIVE
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
ATNR_BLIND
#define ATNR_BLIND
Definition: attack.h:71
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:602
trap_adjust
static void trap_adjust(object *trap, int difficulty)
Adjust trap difficulty to the map.
Definition: treasure.cpp:847
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
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
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:1510
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
treasurelist::name
sstring name
Usually monster-name/combination.
Definition: treasure.h:86
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:1441
tailor_readable_ob
void tailor_readable_ob(object *book, int msg_type)
The main routine.
Definition: readable.cpp:1892
dice2
static int dice2()
Definition: treasure.cpp:895
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:307
isqrt
int isqrt(int n)
Compute the square root.
Definition: utils.cpp:562
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:206
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
INS_NO_MERGE
#define INS_NO_MERGE
Don't try to merge with other items.
Definition: object.h:580
FLAG_DAMNED
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:317
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:56
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
living::food
int32_t food
How much food in stomach.
Definition: living.h:48
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:59
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:66
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_NO_STEAL
#define FLAG_NO_STEAL
Item can't be stolen.
Definition: define.h:342
GET_ANIM_ID
#define GET_ANIM_ID(ob)
Definition: global.h:167
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
set_ring_bonus
static void set_ring_bonus(object *op, int bonus)
Randomly adds one magical ability to the given object.
Definition: treasure.cpp:719
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
treasure::next
treasure * next
Next treasure-item in a linked list.
Definition: treasure.h:69
FLAG_MONSTER
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
fatal
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.cpp:590
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
SHOP_MAT
@ SHOP_MAT
Definition: object.h:189
treasure_remove_item
void treasure_remove_item(treasurelist *list, int position)
Remove the treasure at the specified position from the list.
Definition: treasure.cpp:1485
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:280
living::wc
int8_t wc
Weapon Class, lower WC increases probability of hitting.
Definition: living.h:37
RANDOM
#define RANDOM()
Definition: define.h:638
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:389
ATNR_FIRE
#define ATNR_FIRE
Definition: attack.h:51
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
living::Wis
int8_t Wis
Definition: living.h:36
FLAG_REFL_SPELL
#define FLAG_REFL_SPELL
Spells (some) will reflect from object.
Definition: define.h:275
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
ATNR_DEPLETE
#define ATNR_DEPLETE
Definition: attack.h:65
living::Cha
int8_t Cha
Definition: living.h:36
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:266
object::msg
sstring msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:330
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
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:50
assets.h
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:1312
NUM_ANIMATIONS
#define NUM_ANIMATIONS(ob)
Definition: global.h:173
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:1462
dump_monster_treasure
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.cpp:1284
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:1563
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:308
strcasecmp
int strcasecmp(const char *s1, const char *s2)
AT_ACID
#define AT_ACID
Definition: attack.h:82
loader.h
object::randomitems
struct treasurelist * randomitems
Items to be generated.
Definition: object.h:395
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:286
crown_arch
static archetype * crown_arch
Definition: treasure.cpp:50
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Free inventory objects; if not set, drop inventory.
Definition: object.h:544
ATNR_GHOSTHIT
#define ATNR_GHOSTHIT
Definition: attack.h:58
ATNR_COLD
#define ATNR_COLD
Definition: attack.h:53
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:890
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:52
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
FLAG_CURSED
#define FLAG_CURSED
The object is cursed.
Definition: define.h:316
ATNR_LIFE_STEALING
#define ATNR_LIFE_STEALING
Definition: attack.h:73
generate_artifact
void generate_artifact(object *op, int difficulty)
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:232
FLAG_IS_THROWN
#define FLAG_IS_THROWN
Object is designed to be thrown.
Definition: define.h:249
Settings::armor_speed_improvement
int armor_speed_improvement
Speed improvement.
Definition: global.h:309
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:287
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
MONEY
@ MONEY
Definition: object.h:142
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:63