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