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 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  }
151  give_artifact_abilities(tmp, art->item);
152  } else {
153  fix_generated_item(tmp, op, difficulty, t->magic, flag);
154  change_treasure(t, tmp);
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)
303  object_remove(tmp);
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)
676  SET_FLAG(op, FLAG_CURSED);
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 
823 static void trap_adjust(object *trap, int difficulty) {
824  int i;
825 
826  /* now we set the trap level to match the difficulty of the level
827  * the formula below will give a level from 1 to (2*difficulty) with
828  * a peak probability at difficulty
829  */
830 
831  trap->level = rndm(0, difficulty-1)+rndm(0, difficulty-1);
832  if (trap->level < 1)
833  trap->level = 1;
834 
835  /* set the hiddenness of the trap, similar formula to above */
836  trap->stats.Cha = rndm(0, 19)+rndm(0, difficulty-1)+rndm(0, difficulty-1);
837 
838  if (!trap->other_arch && !trap->inv) {
839  /* set the damage of the trap.
840  * we get 0-4 pts of damage per level of difficulty of the map in
841  * the trap
842  */
843 
844  trap->stats.dam = 0;
845  for (i = 0; i < difficulty; i++)
846  trap->stats.dam += rndm(0, 4);
847 
848  /* the poison trap special case */
849  if (trap->attacktype&AT_POISON) {
850  trap->stats.dam = rndm(0, difficulty-1);
851  if (trap->stats.dam < 1)
852  trap->stats.dam = 1;
853  }
854 
855  /* so we get an appropriate amnt of exp for AT_DEATH traps */
856  if (trap->attacktype&AT_DEATH)
857  trap->stats.dam = 127;
858  }
859 }
860 
861 #define DICE2 (dice2())
862 
866 bool chance(int a, int b) {
867  // Example: chance(2, 3). RANDOM%3 is 0, 1, or 2. 2/3 chance is the result < 2.
868  return RANDOM()%b < a;
869 }
870 
871 static int dice2() {
872  return chance(2, 27) ? 2 : 1;
873 }
874 
875 #define DICESPELL (RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3+RANDOM()%3)
876 
903 void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags) {
904  int was_magic = op->magic, num_enchantments = 0, save_item_power;
905 
906  if (!creator || creator->type == op->type)
907  creator = op; /* safety & to prevent polymorphed objects giving attributes */
908 
909  /* If we make an artifact, this information will be destroyed */
910  save_item_power = op->item_power;
911  op->item_power = 0;
912 
913  if (op->randomitems && op->type != SPELL) {
914  create_treasure(op->randomitems, op, flags, difficulty, 0);
915  if (!op->inv)
916  LOG(llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", op->name);
917  /* So the treasure doesn't get created again */
918  op->randomitems = NULL;
919  }
920 
921  if (difficulty < 1)
922  difficulty = 1;
923  if (!(flags&GT_MINIMAL)) {
924  if (op->arch == crown_arch) {
925  set_magic(difficulty > 25 ? 30 : difficulty+5, op, max_magic, flags);
926  num_enchantments = calc_item_power(op);
927  generate_artifact(op, difficulty);
928  } else {
929  if (!op->magic && max_magic)
930  set_magic(difficulty, op, max_magic, flags);
931  num_enchantments = calc_item_power(op);
932  if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT))
933  || op->type == ROD
934  || difficulty >= 999)
935  generate_artifact(op, difficulty);
936  }
937 
938  /* Object was made an artifact. Calculate its item_power rating.
939  * the item_power in the object is what the artifact adds.
940  */
941  if (op->title) {
942  /* if save_item_power is set, then most likely we started with an
943  * artifact and have added new abilities to it - this is rare, but
944  * but I have seen things like 'strange rings of fire'. So just
945  * figure out the power from the base power plus what this one adds.
946  * Note that since item_power is not quite linear, this actually
947  * ends up being somewhat of a bonus.
948  */
949  if (save_item_power)
950  op->item_power = save_item_power+get_power_from_ench(op->item_power);
951  else
952  op->item_power += get_power_from_ench(num_enchantments);
953  } else if (save_item_power) {
954  /* restore the item_power field to the object if we haven't changed
955  * it. we don't care about num_enchantments - that will basically
956  * just have calculated some value from the base attributes of the
957  * archetype.
958  */
959  op->item_power = save_item_power;
960  } else {
961  /* item_power was zero. This is suspicious, as it may be because it
962  * was never previously calculated. Let's compute a value and see if
963  * it is non-zero. If it indeed is, then assign it as the new
964  * item_power value.
965  * - gros, 21th of July 2006.
966  */
967  op->item_power = calc_item_power(op);
968  save_item_power = op->item_power; /* Just in case it would get used
969  * again below */
970  }
971  } else {
972  /* If flag is GT_MINIMAL, we want to restore item power */
973  op->item_power = save_item_power;
974  }
975 
976  /* materialtype modifications. Note we allow this on artifacts. */
977  set_materialname(op);
978 
979  if (flags&GT_MINIMAL) {
980  if (op->type == POTION)
981  /* Handle healing and magic power potions */
982  if (op->stats.sp && !op->randomitems) {
983  object *tmp;
984  if (spell_mapping[op->stats.sp]) {
986  object_insert_in_ob(tmp, op);
987  }
988  op->stats.sp = 0;
989  }
990  } else if (!op->title) { /* Only modify object if not special */
991  switch (op->type) {
992  case WEAPON:
993  case ARMOUR:
994  case SHIELD:
995  case HELMET:
996  case CLOAK:
997  if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4))
998  set_ring_bonus(op, -DICE2);
999  break;
1000 
1001  case BRACERS:
1002  if (!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED) ? 5 : 20))) {
1004  if (!QUERY_FLAG(op, FLAG_CURSED))
1005  op->value *= 3;
1006  }
1007  break;
1008 
1009  case POTION: {
1010  int too_many_tries = 0, is_special = 0;
1011 
1012  /* Handle healing and magic power potions */
1013  if (op->stats.sp && !op->randomitems) {
1014  object *tmp;
1015 
1016  tmp = create_archetype(spell_mapping[op->stats.sp]);
1017  object_insert_in_ob(tmp, op);
1018  op->stats.sp = 0;
1019  }
1020 
1021  while (!(is_special = special_potion(op)) && !op->inv) {
1022  generate_artifact(op, difficulty);
1023  if (too_many_tries++ > 10)
1024  break;
1025  }
1026  /* don't want to change value for healing/magic power potions,
1027  * since the value set on those is already correct.
1028  */
1029  if (op->inv && op->randomitems) {
1030  /* value multiplier is same as for scrolls */
1031  op->value = (op->value*op->inv->value);
1032  op->level = op->inv->level/2+RANDOM()%difficulty+RANDOM()%difficulty;
1033  } else {
1034  FREE_AND_COPY(op->name, "potion");
1035  FREE_AND_COPY(op->name_pl, "potions");
1036  }
1037  if (!(flags&GT_ONLY_GOOD) && RANDOM()%2)
1038  SET_FLAG(op, FLAG_CURSED);
1039  break;
1040  }
1041 
1042  case AMULET:
1043  if (op->arch == amulet_arch)
1044  op->value *= 5; /* Since it's not just decoration */
1045  /* fall through */
1046  case RING:
1047  if (op->arch == NULL) {
1048  object_remove(op);
1050  op = NULL;
1051  break;
1052  }
1053  if (op->arch != ring_arch && op->arch != amulet_arch)
1054  /* It's a special artifact!*/
1055  break;
1056 
1057  if (GET_ANIM_ID(op))
1058  SET_ANIMATION(op, RANDOM()%((int)NUM_ANIMATIONS(op)));
1059  if (!(flags&GT_ONLY_GOOD) && !(RANDOM()%3))
1060  SET_FLAG(op, FLAG_CURSED);
1062  if (op->type != RING) /* Amulets have only one ability */
1063  break;
1064  if (!(RANDOM()%4)) {
1065  int d = (RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1066  if (d > 0)
1067  op->value *= 3;
1068  set_ring_bonus(op, d);
1069  if (!(RANDOM()%4)) {
1070  int d = (RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED)) ? -DICE2 : DICE2;
1071  if (d > 0)
1072  op->value *= 5;
1073  set_ring_bonus(op, d);
1074  }
1075  }
1076  break;
1077 
1078  case BOOK:
1079  /* Is it an empty book?, if yes lets make a special
1080  * msg for it, and tailor its properties based on the
1081  * creator and/or map level we found it on.
1082  */
1083  if (!op->msg && RANDOM()%10) {
1084  /* set the book level properly */
1085  if (creator->level == 0 || QUERY_FLAG(creator, FLAG_ALIVE)) {
1086  if (op->map && op->map->difficulty)
1087  op->level = RANDOM()%(op->map->difficulty)+RANDOM()%10+1;
1088  else
1089  op->level = RANDOM()%20+1;
1090  } else
1091  op->level = RANDOM()%creator->level;
1092 
1093  tailor_readable_ob(op, creator->stats.sp);
1094  /* books w/ info are worth more! */
1095  if (op->msg != NULL)
1096  op->value *= ((op->level > 10 ? op->level : (op->level+1)/2)*((strlen(op->msg)/250)+1));
1097  /* creator related stuff */
1098 
1099  if (creator->slaying && !op->slaying) /* for check_inv floors */
1100  op->slaying = add_string(creator->slaying);
1101 
1102  /* add exp so reading it gives xp (once)*/
1103  op->stats.exp = op->value > 10000 ? op->value/5 : op->value/10;
1104  }
1105  /* for library, chained books. Note that some monsters have
1106  * no_pick set - we don't want to set no pick in that case. */
1107  if (QUERY_FLAG(creator, FLAG_NO_PICK)
1108  && !QUERY_FLAG(creator, FLAG_MONSTER))
1109  SET_FLAG(op, FLAG_NO_PICK);
1110  break;
1111 
1112  case SPELLBOOK:
1113  op->value = op->value*op->inv->value;
1114  /* add exp so learning gives xp */
1115  op->level = op->inv->level;
1116  op->stats.exp = op->value;
1117  /* some more fun */
1118  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 5) {
1119  if (rndm(1, 6) <= 1)
1120  SET_FLAG(op, FLAG_DAMNED);
1121  else
1122  SET_FLAG(op, FLAG_CURSED);
1123  } else if (rndm(1, 100) <= 1) {
1124  SET_FLAG(op, FLAG_BLESSED);
1125  }
1126  break;
1127 
1128  case WAND:
1129  /* nrof in the treasure list is number of charges,
1130  * not number of wands. So copy that into food (charges),
1131  * and reset nrof.
1132  */
1133  op->stats.food = op->inv->nrof;
1134  op->nrof = 1;
1135  /* If the spell changes by level, choose a random level
1136  * for it, and adjust price. If the spell doesn't
1137  * change by level, just set the wand to the level of
1138  * the spell, and value calculation is simpler.
1139  */
1140  if (op->inv->duration_modifier
1141  || op->inv->dam_modifier
1142  || op->inv->range_modifier) {
1143  op->level = level_for_item(op, difficulty);
1144  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1145  } else {
1146  op->level = op->inv->level;
1147  op->value = op->value*op->inv->value;
1148  }
1149  break;
1150 
1151  case ROD:
1152  op->level = level_for_item(op, difficulty);
1153  rod_adjust(op);
1154  break;
1155 
1156  case SCROLL:
1157  op->level = level_for_item(op, difficulty);
1158  op->value = op->value*op->inv->value*(op->level+50)/(op->inv->level+50);
1159  /* add exp so reading them properly gives xp */
1160  op->stats.exp = op->value/5;
1161  op->nrof = op->inv->nrof;
1162  /* some more fun */
1163  if (!(flags&GT_ONLY_GOOD) && rndm(1, 100) <= 20) {
1164  if (rndm(1, 6) <= 1)
1165  SET_FLAG(op, FLAG_DAMNED);
1166  else
1167  SET_FLAG(op, FLAG_CURSED);
1168  } else if (rndm(1, 100) <= 2) {
1169  SET_FLAG(op, FLAG_BLESSED);
1170  }
1171  break;
1172 
1173  case RUNE:
1174  trap_adjust(op, difficulty);
1175  break;
1176 
1177  case TRAP:
1178  trap_adjust(op, difficulty);
1179  break;
1180  } /* switch type */
1181  }
1182  if (flags&GT_STARTEQUIP) {
1183  if (op->nrof < 2
1184  && op->type != CONTAINER
1185  && op->type != MONEY
1186  && !QUERY_FLAG(op, FLAG_IS_THROWN))
1188  else if (op->type != MONEY)
1189  op->value = 0;
1190  }
1191 
1192  if (!(flags&GT_ENVIRONMENT))
1193  fix_flesh_item(op, creator);
1194 }
1195 
1199 static void dump_monster_treasure_rec(const char *name, treasure *t, int depth) {
1200  treasurelist *tl;
1201  int i;
1202 
1203  if (depth > 100)
1204  return;
1205 
1206  while (t != NULL) {
1207  if (t->name != NULL) {
1208  for (i = 0; i < depth; i++)
1209  fprintf(logfile, " ");
1210  fprintf(logfile, "{ (list: %s)\n", t->name);
1211  tl = find_treasurelist(t->name);
1212  dump_monster_treasure_rec(name, tl->items, depth+2);
1213  for (i = 0; i < depth; i++)
1214  fprintf(logfile, " ");
1215  fprintf(logfile, "} (end of list: %s)\n", t->name);
1216  } else {
1217  for (i = 0; i < depth; i++)
1218  fprintf(logfile, " ");
1219  if (t->item->clone.type == FLESH)
1220  fprintf(logfile, "%s's %s\n", name, t->item->clone.name);
1221  else
1222  fprintf(logfile, "%s\n", t->item->clone.name);
1223  }
1224  if (t->next_yes != NULL) {
1225  for (i = 0; i < depth; i++)
1226  fprintf(logfile, " ");
1227  fprintf(logfile, " (if yes)\n");
1228  dump_monster_treasure_rec(name, t->next_yes, depth+1);
1229  }
1230  if (t->next_no != NULL) {
1231  for (i = 0; i < depth; i++)
1232  fprintf(logfile, " ");
1233  fprintf(logfile, " (if no)\n");
1234  dump_monster_treasure_rec(name, t->next_no, depth+1);
1235  }
1236  t = t->next;
1237  }
1238 }
1239 
1244 void dump_monster_treasure(const char *name) {
1245  int found;
1246 
1247  found = 0;
1248  fprintf(logfile, "\n");
1249  getManager()->archetypes()->each([&] (const auto at) {
1250  if (!strcasecmp(at->clone.name, name) && at->clone.title == NULL) {
1251  fprintf(logfile, "treasures for %s (arch: %s)\n", at->clone.name, at->name);
1252  if (at->clone.randomitems != NULL)
1253  dump_monster_treasure_rec(at->clone.name, at->clone.randomitems->items, 1);
1254  else
1255  fprintf(logfile, "(nothing)\n");
1256  fprintf(logfile, "\n");
1257  found++;
1258  }
1259  });
1260 
1261  if (found == 0)
1262  fprintf(logfile, "No objects have the name %s!\n\n", name);
1263 }
1264 
1272 static void fix_flesh_item(object *item, const object *donor) {
1273  char tmpbuf[MAX_BUF];
1274  int i;
1275 
1276  if (item->type == FLESH && donor && QUERY_FLAG(donor, FLAG_MONSTER)) {
1277  /* change the name */
1278  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name);
1279  FREE_AND_COPY(item->name, tmpbuf);
1280  snprintf(tmpbuf, sizeof(tmpbuf), "%s's %s", donor->name, item->name_pl);
1281  FREE_AND_COPY(item->name_pl, tmpbuf);
1282 
1283  /* store original arch in other_arch */
1284  if (!item->other_arch) {
1285  if (!donor->arch->reference_count) {
1286  item->other_arch = donor->arch;
1287  } else {
1288  /* If dealing with custom monsters, other_arch still needs to
1289  * point back to the original. Otherwise what happens
1290  * is that other_arch points at the custom archetype, but
1291  * that can be freed. Reference count doesn't work because
1292  * the loader will not be able to resolve the other_arch at
1293  * load time (server may has restarted, etc.)
1294  */
1295  archetype *original = find_archetype(donor->arch->name);
1296 
1297  if (original)
1298  item->other_arch = original;
1299  else {
1300  LOG(llevError, "could not find original archetype %s for custom monster!\n", donor->arch->name);
1301  abort();
1302  }
1303  }
1304  }
1305 
1306  /* weight is FLESH weight/100 * donor */
1307  if ((item->weight = (signed long)(((double)item->weight/(double)100.0)*(double)donor->weight)) == 0)
1308  item->weight = 1;
1309 
1310  /* value is multiplied by level of donor */
1311  item->value *= isqrt(donor->level*2);
1312 
1313  /* food value */
1314  item->stats.food += (donor->stats.hp/100)+donor->stats.Con;
1315 
1316  /* flesh items inherit some abilities of donor, but not full effect. */
1317  for (i = 0; i < NROFATTACKS; i++)
1318  item->resist[i] = donor->resist[i]/2;
1319 
1320  /* item inherits donor's level and exp (important for dragons) */
1321  item->level = donor->level;
1322  item->stats.exp = donor->stats.exp;
1323 
1324  /* if donor has some attacktypes, the flesh is poisonous */
1325  if (donor->attacktype&AT_POISON)
1326  item->type = POISON;
1327  if (donor->attacktype&AT_ACID)
1328  item->stats.hp = -1*item->stats.food;
1329  SET_FLAG(item, FLAG_NO_STEAL);
1330 
1331  /* attempt to change the face - will take a face named "donor's arch"_"item's face". We ignore the animation for now */
1332  if (item->face != NULL) {
1333  snprintf(tmpbuf, sizeof(tmpbuf), "%s_%s", donor->arch->name, item->face->name);
1334  item->face = try_find_face(tmpbuf, item->face);
1335  }
1336  }
1337 }
1338 
1347 static int special_potion(object *op) {
1348  int i;
1349 
1350  if (op->attacktype)
1351  return 1;
1352 
1353  if (op->stats.Str
1354  || op->stats.Dex
1355  || op->stats.Con
1356  || op->stats.Pow
1357  || op->stats.Wis
1358  || op->stats.Int
1359  || op->stats.Cha)
1360  return 1;
1361 
1362  for (i = 0; i < NROFATTACKS; i++)
1363  if (op->resist[i])
1364  return 1;
1365 
1366  return 0;
1367 }
1368 
1381  treasure *t = (treasure *)calloc(1, sizeof(treasure));
1382  if (t == NULL)
1384  t->item = NULL;
1385  t->name = NULL;
1386  t->next = NULL;
1387  t->next_yes = NULL;
1388  t->next_no = NULL;
1389  t->chance = 100;
1390  t->magic = 0;
1391  t->nrof = 0;
1392  return t;
1393 }
1394 
1402  if (t->name)
1403  free_string(t->name);
1404  if (t->artifact)
1405  free_string(t->artifact);
1406  if (t->next)
1407  treasure_free(t->next);
1408  if (t->next_yes)
1409  treasure_free(t->next_yes);
1410  if (t->next_no)
1411  treasure_free(t->next_no);
1412  free(t);
1413 }
1414 
1415 
1423  treasure *added = get_empty_treasure();
1424  if (list->items == NULL || position <= 0) {
1425  added->next = list->items;
1426  list->items = added;
1427  return added;
1428  }
1429  treasure *prev = list->items;
1430  position--;
1431  while (position > 0 && prev->next) {
1432  position--;
1433  prev = prev->next;
1434  }
1435  added->next = prev->next;
1436  prev->next = added;
1437  return added;
1438 }
1439 
1446  if (list->items == 0 || position < 0) {
1447  return;
1448  }
1449  if (position == 0) {
1450  treasure *next = list->items->next;
1451  list->items->next = NULL;
1452  treasure_free(list->items);
1453  list->items = next;
1454  return;
1455  }
1456  position--;
1457  treasure *prev = list->items;
1458  while (prev && position > 0) {
1459  position--;
1460  prev = prev->next;
1461  }
1462  if (!prev) {
1463  return;
1464  }
1465  treasure *next = prev->next->next;
1466  prev->next->next = NULL;
1467  treasure_free(prev->next);
1468  prev->next = next;
1469 }
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:666
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
Server 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:618
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:1199
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:861
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:311
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
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:323
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
if
if(!(yy_init))
Definition: loader.cpp:36428
treasurelist::total_chance
int16_t total_chance
If non-zero, only 1 item on this list should be generated.
Definition: treasure.h:87
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:248
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
Definition: treasure.cpp:295
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
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:903
get_power_from_ench
int get_power_from_ench(int ench)
Definition: item.cpp:212
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:1380
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:1347
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:175
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
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:304
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:2857
put_treasure
static void put_treasure(object *op, object *creator, int flags)
Inserts generated treasure where it should go.
Definition: treasure.cpp:82
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:1560
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:578
trap_adjust
static void trap_adjust(object *trap, int difficulty)
Adjust trap difficulty to the map.
Definition: treasure.cpp:823
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
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
ROD
@ ROD
Definition: object.h:114
CONTAINER
@ CONTAINER
Definition: object.h:236
set_attr_value
void set_attr_value(living *stats, int attr, int8_t value)
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:1401
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:871
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:308
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:1592
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:695
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:2100
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:1273
treasure_remove_item
void treasure_remove_item(treasurelist *list, int position)
Remove the treasure at the specified position from the list.
Definition: treasure.cpp:1445
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:365
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:265
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:1272
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:1422
dump_monster_treasure
void dump_monster_treasure(const char *name)
For debugging purposes.
Definition: treasure.cpp:1244
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:309
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:1833
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:285
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:866
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
do_single_item
static void do_single_item(treasure *t, object *op, int flag, int difficulty)
Creates the item for a treasure.
Definition: treasure.cpp:139
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:235
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:210
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:310
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:263
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