ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/treasure.C
Revision: 1.40
Committed: Wed Mar 14 00:04:58 2007 UTC (17 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.39: +4 -4 lines
Log Message:
- rewrote smooth face handling, as a side-effect, smoothing seems to work
  again and smooth faces can be reloaded.
- the server now sends the full animation for an object the first time
  it is seen, this uses slightly more bandwidth initially, but avoids
  the flickering for objects change their face later.

File Contents

# Content
1 /*
2 * CrossFire, A Multiplayer game for X-windows
3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
23 */
24
25 #define ALLOWED_COMBINATION
26
27 /* TREASURE_DEBUG does some checking on the treasurelists after loading.
28 * It is useful for finding bugs in the treasures file. Since it only
29 * slows the startup some (and not actual game play), it is by default
30 * left on
31 */
32 #define TREASURE_DEBUG
33
34 /* TREASURE_VERBOSE enables copious output concerning artifact generation */
35
36 /* #define TREASURE_VERBOSE */
37
38 #include <global.h>
39 #include <treasure.h>
40 #include <funcpoint.h>
41 #include <loader.h>
42
43
44 static void change_treasure (treasure *t, object *op); /* overrule default values */
45 extern char *spell_mapping[];
46
47 /*
48 * Initialize global archtype pointers:
49 */
50
51 void
52 init_archetype_pointers ()
53 {
54 int prev_warn = warn_archetypes;
55
56 warn_archetypes = 1;
57 if (ring_arch == NULL)
58 ring_arch = archetype::find ("ring");
59 if (amulet_arch == NULL)
60 amulet_arch = archetype::find ("amulet");
61 if (staff_arch == NULL)
62 staff_arch = archetype::find ("staff");
63 if (crown_arch == NULL)
64 crown_arch = archetype::find ("crown");
65 warn_archetypes = prev_warn;
66 }
67
68 /*
69 * Allocate and return the pointer to an empty treasurelist structure.
70 */
71
72 static treasurelist *
73 get_empty_treasurelist (void)
74 {
75 return new treasurelist;
76 }
77
78 /*
79 * Allocate and return the pointer to an empty treasure structure.
80 */
81 //TODO: make this a constructor
82 static treasure *
83 get_empty_treasure (void)
84 {
85 treasure *t = new treasure;
86
87 t->chance = 100;
88
89 return t;
90 }
91
92 /*
93 * Reads the lib/treasure file from disk, and parses the contents
94 * into an internal treasure structure (very linked lists)
95 */
96
97 static treasure *
98 load_treasure (FILE * fp, int *line)
99 {
100 char buf[MAX_BUF], *cp, variable[MAX_BUF];
101 treasure *t = get_empty_treasure ();
102 int value;
103
104 nroftreasures++;
105 while (fgets (buf, MAX_BUF, fp) != NULL)
106 {
107 (*line)++;
108
109 if (*buf == '#')
110 continue;
111 if ((cp = strchr (buf, '\n')) != NULL)
112 *cp = '\0';
113 cp = buf;
114 while (isspace (*cp)) /* Skip blanks */
115 cp++;
116
117 if (sscanf (cp, "arch %s", variable))
118 {
119 if ((t->item = archetype::find (variable)) == NULL)
120 LOG (llevError, "Treasure lacks archetype: %s\n", variable);
121 }
122 else if (sscanf (cp, "list %s", variable))
123 t->name = variable;
124 else if (sscanf (cp, "change_name %s", variable))
125 t->change_arch.name = variable;
126 else if (sscanf (cp, "change_title %s", variable))
127 t->change_arch.title = variable;
128 else if (sscanf (cp, "change_slaying %s", variable))
129 t->change_arch.slaying = variable;
130 else if (sscanf (cp, "chance %d", &value))
131 t->chance = (uint8) value;
132 else if (sscanf (cp, "nrof %d", &value))
133 t->nrof = (uint16) value;
134 else if (sscanf (cp, "magic %d", &value))
135 t->magic = (uint8) value;
136 else if (!strcmp (cp, "yes"))
137 t->next_yes = load_treasure (fp, line);
138 else if (!strcmp (cp, "no"))
139 t->next_no = load_treasure (fp, line);
140 else if (!strcmp (cp, "end"))
141 return t;
142 else if (!strcmp (cp, "more"))
143 {
144 t->next = load_treasure (fp, line);
145 return t;
146 }
147 else
148 LOG (llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, &t->name, *line);
149 }
150 LOG (llevError, "treasure lacks 'end'.\n");
151 return t;
152 }
153
154 #ifdef TREASURE_DEBUG
155
156 /* recursived checks the linked list. Treasurelist is passed only
157 * so that the treasure name can be printed out
158 */
159 static void
160 check_treasurelist (const treasure *t, const treasurelist * tl)
161 {
162 if (t->chance >= 100 && t->next_yes && (t->next || t->next_no))
163 LOG (llevError, "Treasurelist %s has element that has 100%% generation, next_yes field as well as next or next_no\n", &tl->name);
164 /* find_treasurelist will print out its own error message */
165 if (t->name && *t->name)
166 find_treasurelist (t->name);
167 if (t->next)
168 check_treasurelist (t->next, tl);
169 if (t->next_yes)
170 check_treasurelist (t->next_yes, tl);
171 if (t->next_no)
172 check_treasurelist (t->next_no, tl);
173 }
174 #endif
175
176 /*
177 * Opens LIBDIR/treasure and reads all treasure-declarations from it.
178 * Each treasure is parsed with the help of load_treasure().
179 */
180
181 void
182 load_treasures (void)
183 {
184 FILE *fp;
185 char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF];
186 treasurelist *previous = NULL;
187 treasure *t;
188 int comp, line = 0;
189
190 sprintf (filename, "%s/%s", settings.datadir, settings.treasures);
191 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
192 {
193 LOG (llevError, "Can't open treasure file.\n");
194 return;
195 }
196 while (fgets (buf, MAX_BUF, fp) != NULL)
197 {
198 line++;
199 if (*buf == '#' || *buf == '\n')
200 ; // ignore
201 else if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name))
202 {
203 treasurelist *tl = get_empty_treasurelist ();
204
205 tl->name = name;
206 if (previous == NULL)
207 first_treasurelist = tl;
208 else
209 previous->next = tl;
210
211 previous = tl;
212 tl->items = load_treasure (fp, &line);
213
214 /* This is a one of the many items on the list should be generated.
215 * Add up the chance total, and check to make sure the yes & no
216 * fields of the treasures are not being used.
217 */
218 if (!strncmp (buf, "treasureone", 11))
219 {
220 for (t = tl->items; t != NULL; t = t->next)
221 {
222 #ifdef TREASURE_DEBUG
223 if (t->next_yes || t->next_no)
224 {
225 LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name);
226 LOG (llevError, " the next_yes or next_no field is set\n");
227 }
228 #endif
229 tl->total_chance += t->chance;
230 }
231 }
232 }
233 else
234 LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line);
235 }
236 close_and_delete (fp, comp);
237
238 #ifdef TREASURE_DEBUG
239 /* Perform some checks on how valid the treasure data actually is.
240 * verify that list transitions work (ie, the list that it is supposed
241 * to transition to exists). Also, verify that at least the name
242 * or archetype is set for each treasure element.
243 */
244 for (previous = first_treasurelist; previous != NULL; previous = previous->next)
245 check_treasurelist (previous->items, previous);
246 #endif
247 }
248
249 /*
250 * Searches for the given treasurelist in the globally linked list
251 * of treasurelists which has been built by load_treasures().
252 */
253
254 treasurelist *
255 find_treasurelist (const char *name)
256 {
257 shstr_cmp name_ (name);
258
259 if (!name_)
260 return 0;
261
262 for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next)
263 if (name_ == tl->name)
264 return tl;
265
266 if (first_treasurelist)
267 LOG (llevError, "Couldn't find treasurelist %s\n", name);
268
269 return 0;
270 }
271
272
273 /*
274 * Generates the objects specified by the given treasure.
275 * It goes recursively through the rest of the linked list.
276 * If there is a certain percental chance for a treasure to be generated,
277 * this is taken into consideration.
278 * The second argument specifies for which object the treasure is
279 * being generated.
280 * If flag is GT_INVISIBLE, only invisible objects are generated (ie, only
281 * abilities. This is used by summon spells, thus no summoned monsters
282 * start with equipment, but only their abilities).
283 */
284 static void
285 put_treasure (object *op, object *creator, int flags)
286 {
287 object *tmp;
288
289 /* Bit of a hack - spells should never be put onto the map. The entire
290 * treasure stuff is a problem - there is no clear idea of knowing
291 * this is the original object, or if this is an object that should be created
292 * by another object.
293 */
294 if (flags & GT_ENVIRONMENT && op->type != SPELL)
295 {
296 SET_FLAG (op, FLAG_OBJ_ORIGINAL);
297 op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON);
298 }
299 else
300 {
301 op = creator->insert (op);
302
303 if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER))
304 monster_check_apply (creator, op);
305
306 if ((flags & GT_UPDATE_INV) && (tmp = creator->in_player ()))
307 esrv_send_item (tmp, op);
308 }
309 }
310
311 /* if there are change_xxx commands in the treasure, we include the changes
312 * in the generated object
313 */
314 static void
315 change_treasure (treasure *t, object *op)
316 {
317 /* CMD: change_name xxxx */
318 if (t->change_arch.name)
319 {
320 op->name = t->change_arch.name;
321 op->name_pl = t->change_arch.name;
322 }
323
324 if (t->change_arch.title)
325 op->title = t->change_arch.title;
326
327 if (t->change_arch.slaying)
328 op->slaying = t->change_arch.slaying;
329 }
330
331 void
332 create_all_treasures (treasure *t, object *op, int flag, int difficulty, int tries)
333 {
334 object *tmp;
335
336 if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance)
337 {
338 if (t->name)
339 {
340 if (difficulty >= t->magic)
341 {
342 treasurelist *tl = find_treasurelist (t->name);
343 if (tl)
344 create_treasure (tl, op, flag, difficulty, tries);
345 }
346 }
347 else
348 {
349 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)))
350 {
351 tmp = arch_to_object (t->item);
352 if (t->nrof && tmp->nrof <= 1)
353 tmp->nrof = rndm (t->nrof) + 1;
354
355 fix_generated_item (tmp, op, difficulty, t->magic, flag);
356 change_treasure (t, tmp);
357 put_treasure (tmp, op, flag);
358 }
359 }
360
361 if (t->next_yes != NULL)
362 create_all_treasures (t->next_yes, op, flag, difficulty, tries);
363 }
364 else if (t->next_no != NULL)
365 create_all_treasures (t->next_no, op, flag, difficulty, tries);
366
367 if (t->next != NULL)
368 create_all_treasures (t->next, op, flag, difficulty, tries);
369 }
370
371 void
372 create_one_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries)
373 {
374 int value = rndm (tl->total_chance);
375 treasure *t;
376
377 if (tries++ > 100)
378 {
379 LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
380 return;
381 }
382
383 for (t = tl->items; t != NULL; t = t->next)
384 {
385 value -= t->chance;
386
387 if (value < 0)
388 break;
389 }
390
391 if (!t || value >= 0)
392 {
393 LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n");
394 abort ();
395 return;
396 }
397
398 if (t->name)
399 {
400 if (difficulty >= t->magic)
401 {
402 treasurelist *tl = find_treasurelist (t->name);
403 if (tl)
404 create_treasure (tl, op, flag, difficulty, tries);
405 }
406 else if (t->nrof)
407 create_one_treasure (tl, op, flag, difficulty, tries);
408
409 return;
410 }
411
412 if (t->item && (t->item->clone.invisible != 0 || flag != GT_INVISIBLE))
413 {
414 object *tmp = arch_to_object (t->item);
415
416 if (!tmp)
417 return;
418
419 if (t->nrof && tmp->nrof <= 1)
420 tmp->nrof = rndm (t->nrof) + 1;
421
422 fix_generated_item (tmp, op, difficulty, t->magic, flag);
423 change_treasure (t, tmp);
424 put_treasure (tmp, op, flag);
425 }
426 }
427
428 /* This calls the appropriate treasure creation function. tries is passed
429 * to determine how many list transitions or attempts to create treasure
430 * have been made. It is really in place to prevent infinite loops with
431 * list transitions, or so that excessively good treasure will not be
432 * created on weak maps, because it will exceed the number of allowed tries
433 * to do that.
434 */
435 void
436 create_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries)
437 {
438 if (tries++ > 100)
439 {
440 LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
441 return;
442 }
443
444 if (tl->total_chance)
445 create_one_treasure (tl, op, flag, difficulty, tries);
446 else
447 create_all_treasures (tl->items, op, flag, difficulty, tries);
448 }
449
450 /* This is similar to the old generate treasure function. However,
451 * it instead takes a treasurelist. It is really just a wrapper around
452 * create_treasure. We create a dummy object that the treasure gets
453 * inserted into, and then return that treausre
454 */
455 object *
456 generate_treasure (treasurelist *tl, int difficulty)
457 {
458 difficulty = clamp (difficulty, 1, settings.max_level);
459
460 object *ob = object::create (), *tmp;
461
462 create_treasure (tl, ob, 0, difficulty, 0);
463
464 /* Don't want to free the object we are about to return */
465 tmp = ob->inv;
466 if (tmp != NULL)
467 tmp->remove ();
468
469 if (ob->inv)
470 LOG (llevError, "In generate treasure, created multiple objects.\n");
471
472 ob->destroy ();
473 return tmp;
474 }
475
476 /*
477 * This is a new way of calculating the chance for an item to have
478 * a specific magical bonus.
479 * The array has two arguments, the difficulty of the level, and the
480 * magical bonus "wanted".
481 */
482
483 static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = {
484
485 /*chance of magic difficulty*/
486
487 /* +0 +1 +2 +3 +4 */
488 {95, 2, 2, 1, 0}, /*1 */
489 {92, 5, 2, 1, 0}, /*2 */
490 {85, 10, 4, 1, 0}, /*3 */
491 {80, 14, 4, 2, 0}, /*4 */
492 {75, 17, 5, 2, 1}, /*5 */
493 {70, 18, 8, 3, 1}, /*6 */
494 {65, 21, 10, 3, 1}, /*7 */
495 {60, 22, 12, 4, 2}, /*8 */
496 {55, 25, 14, 4, 2}, /*9 */
497 {50, 27, 16, 5, 2}, /*10 */
498 {45, 28, 18, 6, 3}, /*11 */
499 {42, 28, 20, 7, 3}, /*12 */
500 {40, 27, 21, 8, 4}, /*13 */
501 {38, 25, 22, 10, 5}, /*14 */
502 {36, 23, 23, 12, 6}, /*15 */
503 {33, 21, 24, 14, 8}, /*16 */
504 {31, 19, 25, 16, 9}, /*17 */
505 {27, 15, 30, 18, 10}, /*18 */
506 {20, 12, 30, 25, 13}, /*19 */
507 {15, 10, 28, 30, 17}, /*20 */
508 {13, 9, 27, 28, 23}, /*21 */
509 {10, 8, 25, 28, 29}, /*22 */
510 {8, 7, 23, 26, 36}, /*23 */
511 {6, 6, 20, 22, 46}, /*24 */
512 {4, 5, 17, 18, 56}, /*25 */
513 {2, 4, 12, 14, 68}, /*26 */
514 {0, 3, 7, 10, 80}, /*27 */
515 {0, 0, 3, 7, 90}, /*28 */
516 {0, 0, 0, 3, 97}, /*29 */
517 {0, 0, 0, 0, 100}, /*30 */
518 {0, 0, 0, 0, 100}, /*31 */
519 };
520
521
522 /* calculate the appropriate level for wands staves and scrolls.
523 * This code presumes that op has had its spell object created (in op->inv)
524 *
525 * elmex Wed Aug 9 17:44:59 CEST 2006:
526 * Removed multiplicator, too many high-level items were generated on low-difficulty maps.
527 */
528
529 int
530 level_for_item (const object *op, int difficulty)
531 {
532 int olevel = 0;
533
534 if (!op->inv)
535 {
536 LOG (llevError, "level_for_item: Object %s has no inventory!\n", &op->name);
537 return 0;
538 }
539
540 olevel = (int) (op->inv->level + (double) difficulty * (1 - drand48 () * drand48 () * 2));
541
542 if (olevel <= 0)
543 olevel = rndm (1, MIN (op->inv->level, 1));
544
545 if (olevel > MAXLEVEL)
546 olevel = MAXLEVEL;
547
548 return olevel;
549 }
550
551 /*
552 * Based upon the specified difficulty and upon the difftomagic_list array,
553 * a random magical bonus is returned. This is used when determine
554 * the magical bonus created on specific maps.
555 *
556 * elmex Thu Aug 10 18:45:44 CEST 2006:
557 * Scaling difficulty by max_level, as difficulty is a level and not some
558 * weird integer between 1-31.
559 *
560 */
561
562 int
563 magic_from_difficulty (int difficulty)
564 {
565 int percent = 0, magic = 0;
566 int scaled_diff = (int) (((double) difficulty / settings.max_level) * DIFFLEVELS);
567
568 scaled_diff--;
569
570 if (scaled_diff < 0)
571 scaled_diff = 0;
572
573 if (scaled_diff >= DIFFLEVELS)
574 scaled_diff = DIFFLEVELS - 1;
575
576 percent = rndm (100);
577
578 for (magic = 0; magic < (MAXMAGIC + 1); magic++)
579 {
580 percent -= difftomagic_list[scaled_diff][magic];
581
582 if (percent < 0)
583 break;
584 }
585
586 if (magic == (MAXMAGIC + 1))
587 {
588 LOG (llevError, "Warning, table for difficulty (scaled %d) %d bad.\n", scaled_diff, difficulty);
589 magic = 0;
590 }
591
592 magic = (rndm (3)) ? magic : -magic;
593 /* LOG(llevDebug, "Chose magic %d for difficulty (scaled %d) %d\n", magic, scaled_diff, difficulty); */
594
595 return magic;
596 }
597
598 /*
599 * Sets magical bonus in an object, and recalculates the effect on
600 * the armour variable, and the effect on speed of armour.
601 * This function doesn't work properly, should add use of archetypes
602 * to make it truly absolute.
603 */
604
605 void
606 set_abs_magic (object *op, int magic)
607 {
608 if (!magic)
609 return;
610
611 op->magic = magic;
612 if (op->arch)
613 {
614 if (op->type == ARMOUR)
615 ARMOUR_SPEED (op) = (ARMOUR_SPEED (&op->arch->clone) * (100 + magic * 10)) / 100;
616
617 if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */
618 magic = (-magic);
619 op->weight = (op->arch->clone.weight * (100 - magic * 10)) / 100;
620 }
621 else
622 {
623 if (op->type == ARMOUR)
624 ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100;
625 if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */
626 magic = (-magic);
627 op->weight = (op->weight * (100 - magic * 10)) / 100;
628 }
629 }
630
631 /*
632 * Sets a random magical bonus in the given object based upon
633 * the given difficulty, and the given max possible bonus.
634 */
635
636 static void
637 set_magic (int difficulty, object *op, int max_magic, int flags)
638 {
639 int i;
640
641 i = magic_from_difficulty (difficulty);
642 if ((flags & GT_ONLY_GOOD) && i < 0)
643 i = -i;
644 if (i > max_magic)
645 i = max_magic;
646 set_abs_magic (op, i);
647 if (i < 0)
648 SET_FLAG (op, FLAG_CURSED);
649 }
650
651 /*
652 * Randomly adds one magical ability to the given object.
653 * Modified for Partial Resistance in many ways:
654 * 1) Since rings can have multiple bonuses, if the same bonus
655 * is rolled again, increase it - the bonuses now stack with
656 * other bonuses previously rolled and ones the item might natively have.
657 * 2) Add code to deal with new PR method.
658 */
659
660 void
661 set_ring_bonus (object *op, int bonus)
662 {
663
664 int r = rndm (bonus > 0 ? 25 : 11);
665
666 if (op->type == AMULET)
667 {
668 if (!(rndm (21)))
669 r = 20 + rndm (2);
670 else
671 {
672 if (rndm (2))
673 r = 10;
674 else
675 r = 11 + rndm (9);
676 }
677 }
678
679 switch (r)
680 {
681 /* Redone by MSW 2000-11-26 to have much less code. Also,
682 * bonuses and penalties will stack and add to existing values.
683 * of the item.
684 */
685 case 0:
686 case 1:
687 case 2:
688 case 3:
689 case 4:
690 case 5:
691 case 6:
692 set_attr_value (&op->stats, r, (signed char) (bonus + get_attr_value (&op->stats, r)));
693 break;
694
695 case 7:
696 op->stats.dam += bonus;
697 break;
698
699 case 8:
700 op->stats.wc += bonus;
701 break;
702
703 case 9:
704 op->stats.food += bonus; /* hunger/sustenance */
705 break;
706
707 case 10:
708 op->stats.ac += bonus;
709 break;
710
711 /* Item that gives protections/vulnerabilities */
712 case 11:
713 case 12:
714 case 13:
715 case 14:
716 case 15:
717 case 16:
718 case 17:
719 case 18:
720 case 19:
721 {
722 int b = 5 + abs (bonus), val, resist = rndm (num_resist_table);
723
724 /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
725 val = 10 + rndm (b) + rndm (b) + rndm (b) + rndm (b);
726
727 /* Cursed items need to have higher negative values to equal out with
728 * positive values for how protections work out. Put another
729 * little random element in since that they don't always end up with
730 * even values.
731 */
732 if (bonus < 0)
733 val = 2 * -val - rndm (b);
734 if (val > 35)
735 val = 35; /* Upper limit */
736 b = 0;
737
738 while (op->resist[resist_table[resist]] != 0 && b < 4)
739 resist = rndm (num_resist_table);
740
741 if (b == 4)
742 return; /* Not able to find a free resistance */
743
744 op->resist[resist_table[resist]] = val;
745 /* We should probably do something more clever here to adjust value
746 * based on how good a resistance we gave.
747 */
748 break;
749 }
750 case 20:
751 if (op->type == AMULET)
752 {
753 SET_FLAG (op, FLAG_REFL_SPELL);
754 op->value *= 11;
755 }
756 else
757 {
758 op->stats.hp = 1; /* regenerate hit points */
759 op->value *= 4;
760 }
761 break;
762
763 case 21:
764 if (op->type == AMULET)
765 {
766 SET_FLAG (op, FLAG_REFL_MISSILE);
767 op->value *= 9;
768 }
769 else
770 {
771 op->stats.sp = 1; /* regenerate spell points */
772 op->value *= 3;
773 }
774 break;
775
776 case 22:
777 op->stats.exp += bonus; /* Speed! */
778 op->value = (op->value * 2) / 3;
779 break;
780 }
781
782 if (bonus > 0)
783 op->value *= 2 * bonus;
784 else
785 op->value = -(op->value * 2 * bonus) / 3;
786 }
787
788 /*
789 * get_magic(diff) will return a random number between 0 and 4.
790 * diff can be any value above 2. The higher the diff-variable, the
791 * higher is the chance of returning a low number.
792 * It is only used in fix_generated_treasure() to set bonuses on
793 * rings and amulets.
794 * Another scheme is used to calculate the magic of weapons and armours.
795 */
796 int
797 get_magic (int diff)
798 {
799 int i;
800
801 if (diff < 3)
802 diff = 3;
803
804 for (i = 0; i < 4; i++)
805 if (rndm (diff))
806 return i;
807
808 return 4;
809 }
810
811 #define DICE2 (get_magic(2)==2?2:1)
812 #define DICESPELL (rndm (3) + rndm (3) + rndm (3) + rndm (3) + rndm (3))
813
814 /*
815 * fix_generated_item(): This is called after an item is generated, in
816 * order to set it up right. This produced magical bonuses, puts spells
817 * into scrolls/books/wands, makes it unidentified, hides the value, etc.
818 */
819
820 /* 4/28/96 added creator object from which op may now inherit properties based on
821 * op->type. Right now, which stuff the creator passes on is object type
822 * dependant. I know this is a spagetti manuever, but is there a cleaner
823 * way to do this? b.t. */
824
825 /*
826 * ! (flags & GT_ENVIRONMENT):
827 * Automatically calls fix_flesh_item().
828 *
829 * flags:
830 * GT_STARTEQUIP: Sets FLAG_STARTEQIUP on item if appropriate, or clears the item's
831 * value.
832 * GT_MINIMAL: Does minimal processing on the object - just enough to make it
833 * a working object - don't change magic, value, etc, but set it material
834 * type as appropriate, for objects that need spell objects, set those, etc
835 */
836 void
837 fix_generated_item (object *op, object *creator, int difficulty, int max_magic, int flags)
838 {
839 int was_magic = op->magic, num_enchantments = 0, save_item_power = 0;
840
841 if (!creator || creator->type == op->type)
842 creator = op; /*safety & to prevent polymorphed objects giving attributes */
843
844 /* If we make an artifact, this information will be destroyed */
845 save_item_power = op->item_power;
846 op->item_power = 0;
847
848 if (op->randomitems && op->type != SPELL)
849 {
850 create_treasure (op->randomitems, op, flags, difficulty, 0);
851 if (!op->inv)
852 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", &op->name);
853
854 /* So the treasure doesn't get created again */
855 op->randomitems = NULL;
856 }
857
858 if (difficulty < 1)
859 difficulty = 1;
860
861 if (INVOKE_OBJECT (ADD_BONUS, op,
862 ARG_OBJECT (creator != op ? creator : 0),
863 ARG_INT (difficulty), ARG_INT (max_magic),
864 ARG_INT (flags)))
865 return;
866
867 if (!(flags & GT_MINIMAL))
868 {
869 if (op->arch == crown_arch)
870 {
871 set_magic (difficulty, op, max_magic, flags);
872 num_enchantments = calc_item_power (op, 1);
873 generate_artifact (op, difficulty);
874 }
875 else
876 {
877 if (!op->magic && max_magic)
878 set_magic (difficulty, op, max_magic, flags);
879
880 num_enchantments = calc_item_power (op, 1);
881
882 if ((!was_magic && !rndm (CHANCE_FOR_ARTIFACT))
883 || op->type == HORN
884 || difficulty >= settings.max_level) /* high difficulties always generate an artifact,
885 * used for shop_floors or treasures */
886 generate_artifact (op, difficulty);
887 }
888
889 /* Object was made an artifact. Calculate its item_power rating.
890 * the item_power in the object is what the artfiact adds.
891 */
892 if (op->title)
893 {
894 /* if save_item_power is set, then most likely we started with an
895 * artifact and have added new abilities to it - this is rare, but
896 * but I have seen things like 'strange rings of fire'. So just figure
897 * out the power from the base power plus what this one adds. Note
898 * that since item_power is not quite linear, this actually ends up
899 * being somewhat of a bonus
900 */
901 if (save_item_power)
902 op->item_power = save_item_power + get_power_from_ench (op->item_power);
903 else
904 op->item_power = get_power_from_ench (op->item_power + num_enchantments);
905 }
906 else if (save_item_power)
907 {
908 /* restore the item_power field to the object if we haven't changed it.
909 * we don't care about num_enchantments - that will basically just
910 * have calculated some value from the base attributes of the archetype.
911 */
912 op->item_power = save_item_power;
913 }
914 else
915 {
916 /* item_power was zero. This is suspicious, as it may be because it
917 * was never previously calculated. Let's compute a value and see if
918 * it is non-zero. If it indeed is, then assign it as the new
919 * item_power value.
920 * - gros, 21th of July 2006.
921 */
922 op->item_power = calc_item_power (op, 0);
923 save_item_power = op->item_power; /* Just in case it would get used
924 * again below */
925 }
926 }
927
928 /* materialtype modifications. Note we allow this on artifacts. */
929 set_materialname (op, difficulty, NULL);
930
931 if (flags & GT_MINIMAL)
932 {
933 if (op->type == POTION)
934 /* Handle healing and magic power potions */
935 if (op->stats.sp && !op->randomitems)
936 {
937 object *tmp;
938
939 tmp = get_archetype (spell_mapping[op->stats.sp]);
940 insert_ob_in_ob (tmp, op);
941 op->stats.sp = 0;
942 }
943 }
944 else if (!op->title) /* Only modify object if not special */
945 switch (op->type)
946 {
947 case WEAPON:
948 case ARMOUR:
949 case SHIELD:
950 case HELMET:
951 case CLOAK:
952 if (QUERY_FLAG (op, FLAG_CURSED) && !(rndm (4)))
953 set_ring_bonus (op, -DICE2);
954 break;
955
956 case BRACERS:
957 if (!rndm (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20))
958 {
959 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
960 if (!QUERY_FLAG (op, FLAG_CURSED))
961 op->value *= 3;
962 }
963 break;
964
965 case POTION:
966 {
967 int too_many_tries = 0, is_special = 0;
968
969 /* Handle healing and magic power potions */
970 if (op->stats.sp && !op->randomitems)
971 {
972 object *tmp;
973
974 tmp = get_archetype (spell_mapping[op->stats.sp]);
975 insert_ob_in_ob (tmp, op);
976 op->stats.sp = 0;
977 }
978
979 while (!(is_special = special_potion (op)) && !op->inv)
980 {
981 generate_artifact (op, difficulty);
982 if (too_many_tries++ > 10)
983 break;
984 }
985
986 /* don't want to change value for healing/magic power potions,
987 * since the value set on those is already correct.
988 */
989 if (op->inv && op->randomitems)
990 {
991 /* value multiplier is same as for scrolls */
992 op->value = (op->value * op->inv->value);
993 op->level = op->inv->level / 2 + rndm (difficulty) + rndm (difficulty);
994 }
995 else
996 {
997 op->name = "potion";
998 op->name_pl = "potions";
999 }
1000
1001 if (!(flags & GT_ONLY_GOOD) && rndm (2))
1002 SET_FLAG (op, FLAG_CURSED);
1003 break;
1004 }
1005
1006 case AMULET:
1007 if (op->arch == amulet_arch)
1008 op->value *= 5; /* Since it's not just decoration */
1009
1010 case RING:
1011 if (op->arch == NULL)
1012 {
1013 op->destroy ();
1014 op = 0;
1015 break;
1016 }
1017
1018 if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */
1019 break;
1020
1021 if (!(flags & GT_ONLY_GOOD) && !(rndm (3)))
1022 SET_FLAG (op, FLAG_CURSED);
1023
1024 set_ring_bonus (op, QUERY_FLAG (op, FLAG_CURSED) ? -DICE2 : DICE2);
1025
1026 if (op->type != RING) /* Amulets have only one ability */
1027 break;
1028
1029 if (!(rndm (4)))
1030 {
1031 int d = (rndm (2) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1032
1033 if (d > 0)
1034 op->value *= 3;
1035
1036 set_ring_bonus (op, d);
1037
1038 if (!(rndm (4)))
1039 {
1040 int d = (rndm (3) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1041
1042 if (d > 0)
1043 op->value *= 5;
1044 set_ring_bonus (op, d);
1045 }
1046 }
1047
1048 if (GET_ANIM_ID (op))
1049 SET_ANIMATION (op, rndm (NUM_ANIMATIONS (op)));
1050
1051 break;
1052
1053 case BOOK:
1054 /* Is it an empty book?, if yes lets make a special·
1055 * msg for it, and tailor its properties based on the·
1056 * creator and/or map level we found it on.
1057 */
1058 if (!op->msg && rndm (10))
1059 {
1060 /* set the book level properly */
1061 if (creator->level == 0 || QUERY_FLAG (creator, FLAG_ALIVE))
1062 {
1063 if (op->map && op->map->difficulty)
1064 op->level = rndm (op->map->difficulty) + rndm (10) + 1;
1065 else
1066 op->level = rndm (20) + 1;
1067 }
1068 else
1069 op->level = rndm (creator->level);
1070
1071 tailor_readable_ob (op, (creator && creator->stats.sp) ? creator->stats.sp : -1);
1072 /* books w/ info are worth more! */
1073 op->value *= ((op->level > 10 ? op->level : (op->level + 1) / 2) * ((strlen (op->msg) / 250) + 1));
1074 /* creator related stuff */
1075
1076 /* for library, chained books. Note that some monsters have no_pick
1077 * set - we don't want to set no pick in that case.
1078 */
1079 if (QUERY_FLAG (creator, FLAG_NO_PICK) && !QUERY_FLAG (creator, FLAG_MONSTER))
1080 SET_FLAG (op, FLAG_NO_PICK);
1081 if (creator->slaying && !op->slaying) /* for check_inv floors */
1082 op->slaying = creator->slaying;
1083
1084 /* add exp so reading it gives xp (once) */
1085 op->stats.exp = op->value > 10000 ? op->value / 5 : op->value / 10;
1086 }
1087 break;
1088
1089 case SPELLBOOK:
1090 op->value = op->value * op->inv->value;
1091 /* add exp so learning gives xp */
1092 op->level = op->inv->level;
1093 op->stats.exp = op->value;
1094 break;
1095
1096 case WAND:
1097 /* nrof in the treasure list is number of charges,
1098 * not number of wands. So copy that into food (charges),
1099 * and reset nrof.
1100 */
1101 op->stats.food = op->inv->nrof;
1102 op->nrof = 1;
1103 /* If the spell changes by level, choose a random level
1104 * for it, and adjust price. If the spell doesn't
1105 * change by level, just set the wand to the level of
1106 * the spell, and value calculation is simpler.
1107 */
1108 if (op->inv->duration_modifier || op->inv->dam_modifier || op->inv->range_modifier)
1109 {
1110 op->level = level_for_item (op, difficulty);
1111 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1112 }
1113 else
1114 {
1115 op->level = op->inv->level;
1116 op->value = op->value * op->inv->value;
1117 }
1118 break;
1119
1120 case ROD:
1121 op->level = level_for_item (op, difficulty);
1122 /* Add 50 to both level an divisor to keep prices a little more
1123 * reasonable. Otherwise, a high level version of a low level
1124 * spell can be worth tons a money (eg, level 20 rod, level 2 spell =
1125 * 10 time multiplier). This way, the value are a bit more reasonable.
1126 */
1127 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1128 /* maxhp is used to denote how many 'charges' the rod holds before */
1129 if (op->stats.maxhp)
1130 op->stats.maxhp *= MAX (op->inv->stats.sp, op->inv->stats.grace);
1131 else
1132 op->stats.maxhp = 2 * MAX (op->inv->stats.sp, op->inv->stats.grace);
1133
1134 op->stats.hp = op->stats.maxhp;
1135 break;
1136
1137 case SCROLL:
1138 op->level = level_for_item (op, difficulty);
1139 op->value = op->value * op->inv->value * (op->level + 50) / (op->inv->level + 50);
1140
1141 /* add exp so reading them properly gives xp */
1142 op->stats.exp = op->value / 5;
1143 op->nrof = op->inv->nrof;
1144 break;
1145
1146 case RUNE:
1147 trap_adjust (op, difficulty);
1148 break;
1149
1150 case TRAP:
1151 trap_adjust (op, difficulty);
1152 break;
1153 } /* switch type */
1154
1155 if (flags & GT_STARTEQUIP)
1156 {
1157 if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN))
1158 SET_FLAG (op, FLAG_STARTEQUIP);
1159 else if (op->type != MONEY)
1160 op->value = 0;
1161 }
1162
1163 if (!(flags & GT_ENVIRONMENT))
1164 fix_flesh_item (op, creator);
1165 }
1166
1167 /*
1168 *
1169 *
1170 * CODE DEALING WITH ARTIFACTS STARTS HERE
1171 *
1172 *
1173 */
1174
1175 /*
1176 * Allocate and return the pointer to an empty artifactlist structure.
1177 */
1178 static artifactlist *
1179 get_empty_artifactlist (void)
1180 {
1181 artifactlist *al = (artifactlist *) malloc (sizeof (artifactlist));
1182
1183 if (al == NULL)
1184 fatal (OUT_OF_MEMORY);
1185 al->next = NULL;
1186 al->items = NULL;
1187 al->total_chance = 0;
1188 return al;
1189 }
1190
1191 /*
1192 * Allocate and return the pointer to an empty artifact structure.
1193 */
1194 static artifact *
1195 get_empty_artifact (void)
1196 {
1197 artifact *a = (artifact *) malloc (sizeof (artifact));
1198
1199 if (a == NULL)
1200 fatal (OUT_OF_MEMORY);
1201
1202 a->item = NULL;
1203 a->next = NULL;
1204 a->chance = 0;
1205 a->difficulty = 0;
1206 a->allowed = NULL;
1207 return a;
1208 }
1209
1210 /*
1211 * Searches the artifact lists and returns one that has the same type
1212 * of objects on it.
1213 */
1214 artifactlist *
1215 find_artifactlist (int type)
1216 {
1217 artifactlist *al;
1218
1219 for (al = first_artifactlist; al; al = al->next)
1220 if (al->type == type)
1221 return al;
1222
1223 return 0;
1224 }
1225
1226 /*
1227 * For debugging purposes. Dumps all tables.
1228 */
1229 void
1230 dump_artifacts (void)
1231 {
1232 artifactlist *al;
1233 artifact *art;
1234 linked_char *next;
1235
1236 fprintf (logfile, "\n");
1237 for (al = first_artifactlist; al != NULL; al = al->next)
1238 {
1239 fprintf (logfile, "Artifact has type %d, total_chance=%d\n", al->type, al->total_chance);
1240 for (art = al->items; art != NULL; art = art->next)
1241 {
1242 fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance);
1243 if (art->allowed != NULL)
1244 {
1245 fprintf (logfile, "\tallowed combinations:");
1246 for (next = art->allowed; next != NULL; next = next->next)
1247 fprintf (logfile, "%s,", &next->name);
1248 fprintf (logfile, "\n");
1249 }
1250 }
1251 }
1252 fprintf (logfile, "\n");
1253 }
1254
1255 /*
1256 * For debugging purposes. Dumps all treasures recursively (see below).
1257 */
1258 void
1259 dump_monster_treasure_rec (const char *name, treasure *t, int depth)
1260 {
1261 treasurelist *tl;
1262 int i;
1263
1264 if (depth > 100)
1265 return;
1266 while (t)
1267 {
1268 if (t->name)
1269 {
1270 for (i = 0; i < depth; i++)
1271 fprintf (logfile, " ");
1272 fprintf (logfile, "{ (list: %s)\n", &t->name);
1273 tl = find_treasurelist (t->name);
1274 if (tl)
1275 dump_monster_treasure_rec (name, tl->items, depth + 2);
1276 for (i = 0; i < depth; i++)
1277 fprintf (logfile, " ");
1278 fprintf (logfile, "} (end of list: %s)\n", &t->name);
1279 }
1280 else
1281 {
1282 for (i = 0; i < depth; i++)
1283 fprintf (logfile, " ");
1284 if (t->item && t->item->clone.type == FLESH)
1285 fprintf (logfile, "%s's %s\n", name, &t->item->clone.name);
1286 else
1287 fprintf (logfile, "%s\n", &t->item->clone.name);
1288 }
1289
1290 if (t->next_yes)
1291 {
1292 for (i = 0; i < depth; i++)
1293 fprintf (logfile, " ");
1294 fprintf (logfile, " (if yes)\n");
1295 dump_monster_treasure_rec (name, t->next_yes, depth + 1);
1296 }
1297
1298 if (t->next_no)
1299 {
1300 for (i = 0; i < depth; i++)
1301 fprintf (logfile, " ");
1302 fprintf (logfile, " (if no)\n");
1303 dump_monster_treasure_rec (name, t->next_no, depth + 1);
1304 }
1305
1306 t = t->next;
1307 }
1308 }
1309
1310 /*
1311 * For debugging purposes. Dumps all treasures for a given monster.
1312 * Created originally by Raphael Quinet for debugging the alchemy code.
1313 */
1314
1315 void
1316 dump_monster_treasure (const char *name)
1317 {
1318 archetype *at;
1319 int found;
1320
1321 found = 0;
1322 fprintf (logfile, "\n");
1323
1324 for (at = first_archetype; at != NULL; at = at->next)
1325 if (!strcasecmp (at->clone.name, name) && at->clone.title == NULL)
1326 {
1327 fprintf (logfile, "treasures for %s (arch: %s)\n", &at->clone.name, &at->name);
1328 if (at->clone.randomitems != NULL)
1329 dump_monster_treasure_rec (at->clone.name, at->clone.randomitems->items, 1);
1330 else
1331 fprintf (logfile, "(nothing)\n");
1332
1333 fprintf (logfile, "\n");
1334 found++;
1335 }
1336
1337 if (found == 0)
1338 fprintf (logfile, "No objects have the name %s!\n\n", name);
1339 }
1340
1341 /*
1342 * Builds up the lists of artifacts from the file in the libdir.
1343 */
1344 void
1345 init_artifacts (void)
1346 {
1347 static int has_been_inited = 0;
1348 char filename[MAX_BUF];
1349 artifact *art = NULL;
1350 artifactlist *al;
1351
1352 if (has_been_inited)
1353 return;
1354 else
1355 has_been_inited = 1;
1356
1357 sprintf (filename, "%s/artifacts", settings.datadir);
1358 object_thawer f (filename);
1359
1360 if (!f)
1361 return;
1362
1363 f.next ();
1364
1365 for (;;)
1366 {
1367 switch (f.kw)
1368 {
1369 case KW_allowed:
1370 if (!art)
1371 {
1372 art = get_empty_artifact ();
1373 nrofartifacts++;
1374 }
1375
1376 {
1377 if (!strcmp (f.get_str (), "all"))
1378 break;
1379
1380 char *next, *cp = f.get_str ();
1381
1382 do
1383 {
1384 nrofallowedstr++;
1385
1386 if ((next = strchr (cp, ',')))
1387 *next++ = '\0';
1388
1389 linked_char *tmp = new linked_char;
1390
1391 tmp->name = cp;
1392 tmp->next = art->allowed;
1393 art->allowed = tmp;
1394 }
1395 while ((cp = next));
1396 }
1397 break;
1398
1399 case KW_chance:
1400 f.get (art->chance);
1401 break;
1402
1403 case KW_difficulty:
1404 f.get (art->difficulty);
1405 break;
1406
1407 case KW_object:
1408 {
1409 art->item = object::create ();
1410
1411 if (!art->item->parse_kv (f))
1412 LOG (llevError, "Init_Artifacts: Could not load object.\n");
1413
1414 al = find_artifactlist (art->item->type);
1415
1416 if (!al)
1417 {
1418 al = get_empty_artifactlist ();
1419 al->type = art->item->type;
1420 al->next = first_artifactlist;
1421 first_artifactlist = al;
1422 }
1423
1424 art->next = al->items;
1425 al->items = art;
1426 art = 0;
1427 }
1428 continue;
1429
1430 case KW_EOF:
1431 goto done;
1432
1433 default:
1434 if (!f.parse_error ("artifacts file"))
1435 cleanup ("artifacts file required");
1436 break;
1437 }
1438
1439 f.next ();
1440 }
1441
1442 done:
1443 for (al = first_artifactlist; al; al = al->next)
1444 {
1445 for (art = al->items; art; art = art->next)
1446 {
1447 if (!art->chance)
1448 LOG (llevError, "Warning: artifact with no chance: %s\n", &art->item->name);
1449 else
1450 al->total_chance += art->chance;
1451 }
1452 #if 0
1453 LOG (llevDebug, "Artifact list type %d has %d total chance\n", al->type, al->total_chance);
1454 #endif
1455 }
1456
1457 LOG (llevDebug, "done.\n");
1458 }
1459
1460
1461 /*
1462 * Used in artifact generation. The bonuses of the first object
1463 * is modified by the bonuses of the second object.
1464 */
1465
1466 void
1467 add_abilities (object *op, object *change)
1468 {
1469 int i, tmp;
1470
1471 if (change->face != blank_face)
1472 {
1473 #ifdef TREASURE_VERBOSE
1474 LOG (llevDebug, "FACE: %d\n", change->face->number);
1475 #endif
1476 op->face = change->face;
1477 }
1478
1479 for (i = 0; i < NUM_STATS; i++)
1480 change_attr_value (&(op->stats), i, get_attr_value (&(change->stats), i));
1481
1482 op->attacktype |= change->attacktype;
1483 op->path_attuned |= change->path_attuned;
1484 op->path_repelled |= change->path_repelled;
1485 op->path_denied |= change->path_denied;
1486 op->move_type |= change->move_type;
1487 op->stats.luck += change->stats.luck;
1488
1489 if (QUERY_FLAG (change, FLAG_CURSED))
1490 SET_FLAG (op, FLAG_CURSED);
1491 if (QUERY_FLAG (change, FLAG_DAMNED))
1492 SET_FLAG (op, FLAG_DAMNED);
1493 if ((QUERY_FLAG (change, FLAG_CURSED) || QUERY_FLAG (change, FLAG_DAMNED)) && op->magic > 0)
1494 set_abs_magic (op, -op->magic);
1495
1496 if (QUERY_FLAG (change, FLAG_LIFESAVE))
1497 SET_FLAG (op, FLAG_LIFESAVE);
1498 if (QUERY_FLAG (change, FLAG_REFL_SPELL))
1499 SET_FLAG (op, FLAG_REFL_SPELL);
1500 if (QUERY_FLAG (change, FLAG_STEALTH))
1501 SET_FLAG (op, FLAG_STEALTH);
1502 if (QUERY_FLAG (change, FLAG_XRAYS))
1503 SET_FLAG (op, FLAG_XRAYS);
1504 if (QUERY_FLAG (change, FLAG_BLIND))
1505 SET_FLAG (op, FLAG_BLIND);
1506 if (QUERY_FLAG (change, FLAG_SEE_IN_DARK))
1507 SET_FLAG (op, FLAG_SEE_IN_DARK);
1508 if (QUERY_FLAG (change, FLAG_REFL_MISSILE))
1509 SET_FLAG (op, FLAG_REFL_MISSILE);
1510 if (QUERY_FLAG (change, FLAG_MAKE_INVIS))
1511 SET_FLAG (op, FLAG_MAKE_INVIS);
1512
1513 if (QUERY_FLAG (change, FLAG_STAND_STILL))
1514 {
1515 CLEAR_FLAG (op, FLAG_ANIMATE);
1516 /* so artifacts will join */
1517 if (!QUERY_FLAG (op, FLAG_ALIVE))
1518 op->speed = 0.0;
1519
1520 op->set_speed (op->speed);
1521 }
1522
1523 if (change->nrof)
1524 op->nrof = rndm (change->nrof) + 1;
1525
1526 op->stats.exp += change->stats.exp; /* Speed modifier */
1527 op->stats.wc += change->stats.wc;
1528 op->stats.ac += change->stats.ac;
1529
1530 if (change->other_arch)
1531 {
1532 /* Basically, for horns & potions, the other_arch field is the spell
1533 * to cast. So convert that to into a spell and put it into
1534 * this object.
1535 */
1536 if (op->type == HORN || op->type == POTION)
1537 {
1538 object *tmp_obj;
1539
1540 /* Remove any spells this object currently has in it */
1541 while (op->inv)
1542 op->inv->destroy ();
1543
1544 tmp_obj = arch_to_object (change->other_arch);
1545 insert_ob_in_ob (tmp_obj, op);
1546 }
1547 /* No harm setting this for potions/horns */
1548 op->other_arch = change->other_arch;
1549 }
1550
1551 if (change->stats.hp < 0)
1552 op->stats.hp = -change->stats.hp;
1553 else
1554 op->stats.hp += change->stats.hp;
1555
1556 if (change->stats.maxhp < 0)
1557 op->stats.maxhp = -change->stats.maxhp;
1558 else
1559 op->stats.maxhp += change->stats.maxhp;
1560
1561 if (change->stats.sp < 0)
1562 op->stats.sp = -change->stats.sp;
1563 else
1564 op->stats.sp += change->stats.sp;
1565
1566 if (change->stats.maxsp < 0)
1567 op->stats.maxsp = -change->stats.maxsp;
1568 else
1569 op->stats.maxsp += change->stats.maxsp;
1570
1571 if (change->stats.food < 0)
1572 op->stats.food = -(change->stats.food);
1573 else
1574 op->stats.food += change->stats.food;
1575
1576 if (change->level < 0)
1577 op->level = -(change->level);
1578 else
1579 op->level += change->level;
1580
1581 if (change->gen_sp_armour < 0)
1582 op->gen_sp_armour = -(change->gen_sp_armour);
1583 else
1584 op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100;
1585
1586 op->item_power = change->item_power;
1587
1588 for (i = 0; i < NROFATTACKS; i++)
1589 if (change->resist[i])
1590 op->resist[i] += change->resist[i];
1591
1592 if (change->stats.dam)
1593 {
1594 if (change->stats.dam < 0)
1595 op->stats.dam = (-change->stats.dam);
1596 else if (op->stats.dam)
1597 {
1598 tmp = (signed char) (((int) op->stats.dam * (int) change->stats.dam) / 10);
1599 if (tmp == op->stats.dam)
1600 {
1601 if (change->stats.dam < 10)
1602 op->stats.dam--;
1603 else
1604 op->stats.dam++;
1605 }
1606 else
1607 op->stats.dam = tmp;
1608 }
1609 }
1610
1611 if (change->weight)
1612 {
1613 if (change->weight < 0)
1614 op->weight = (-change->weight);
1615 else
1616 op->weight = (op->weight * (change->weight)) / 100;
1617 }
1618
1619 if (change->last_sp)
1620 {
1621 if (change->last_sp < 0)
1622 op->last_sp = (-change->last_sp);
1623 else
1624 op->last_sp = (signed char) (((int) op->last_sp * (int) change->last_sp) / (int) 100);
1625 }
1626
1627 if (change->gen_sp_armour)
1628 {
1629 if (change->gen_sp_armour < 0)
1630 op->gen_sp_armour = (-change->gen_sp_armour);
1631 else
1632 op->gen_sp_armour = (signed char) (((int) op->gen_sp_armour * ((int) change->gen_sp_armour)) / (int) 100);
1633 }
1634
1635 op->value *= change->value;
1636
1637 if (change->materials)
1638 op->materials = change->materials;
1639
1640 if (change->materialname)
1641 op->materialname = change->materialname;
1642
1643 if (change->slaying)
1644 op->slaying = change->slaying;
1645
1646 if (change->race)
1647 op->race = change->race;
1648
1649 if (change->msg)
1650 op->msg = change->msg;
1651 }
1652
1653 static int
1654 legal_artifact_combination (object *op, artifact * art)
1655 {
1656 int neg, success = 0;
1657 linked_char *tmp;
1658 const char *name;
1659
1660 if (art->allowed == (linked_char *) NULL)
1661 return 1; /* Ie, "all" */
1662 for (tmp = art->allowed; tmp; tmp = tmp->next)
1663 {
1664 #ifdef TREASURE_VERBOSE
1665 LOG (llevDebug, "legal_art: %s\n", tmp->name);
1666 #endif
1667 if (*tmp->name == '!')
1668 name = tmp->name + 1, neg = 1;
1669 else
1670 name = tmp->name, neg = 0;
1671
1672 /* If we match name, then return the opposite of 'neg' */
1673 if (!strcmp (name, op->name) || (op->arch && !strcmp (name, op->arch->name)))
1674 return !neg;
1675
1676 /* Set success as true, since if the match was an inverse, it means
1677 * everything is allowed except what we match
1678 */
1679 else if (neg)
1680 success = 1;
1681 }
1682 return success;
1683 }
1684
1685 /*
1686 * Fixes the given object, giving it the abilities and titles
1687 * it should have due to the second artifact-template.
1688 */
1689
1690 void
1691 give_artifact_abilities (object *op, object *artifct)
1692 {
1693 char new_name[MAX_BUF];
1694
1695 sprintf (new_name, "of %s", &artifct->name);
1696 op->title = new_name;
1697 add_abilities (op, artifct); /* Give out the bonuses */
1698
1699 #if 0 /* Bit verbose, but keep it here until next time I need it... */
1700 {
1701 char identified = QUERY_FLAG (op, FLAG_IDENTIFIED);
1702
1703 SET_FLAG (op, FLAG_IDENTIFIED);
1704 LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL));
1705 if (!identified)
1706 CLEAR_FLAG (op, FLAG_IDENTIFIED);
1707 }
1708 #endif
1709 return;
1710 }
1711
1712 /*
1713 * Decides randomly which artifact the object should be
1714 * turned into. Makes sure that the item can become that
1715 * artifact (means magic, difficulty, and Allowed fields properly).
1716 * Then calls give_artifact_abilities in order to actually create
1717 * the artifact.
1718 */
1719
1720 /* Give 1 re-roll attempt per artifact */
1721 #define ARTIFACT_TRIES 2
1722
1723 void
1724 generate_artifact (object *op, int difficulty)
1725 {
1726 artifactlist *al;
1727 artifact *art;
1728 int i;
1729
1730 al = find_artifactlist (op->type);
1731
1732 if (al == NULL)
1733 {
1734 #if 0 /* This is too verbose, usually */
1735 LOG (llevDebug, "Couldn't change %s into artifact - no table.\n", op->name);
1736 #endif
1737 return;
1738 }
1739
1740 for (i = 0; i < ARTIFACT_TRIES; i++)
1741 {
1742 int roll = rndm (al->total_chance);
1743
1744 for (art = al->items; art; art = art->next)
1745 {
1746 roll -= art->chance;
1747 if (roll < 0)
1748 break;
1749 }
1750
1751 if (art == NULL || roll >= 0)
1752 {
1753 #if 1
1754 LOG (llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", op->type);
1755 #endif
1756 return;
1757 }
1758 if (!strcmp (art->item->name, "NONE"))
1759 return;
1760 if (FABS (op->magic) < art->item->magic)
1761 continue; /* Not magic enough to be this item */
1762
1763 /* Map difficulty not high enough */
1764 if (difficulty < art->difficulty)
1765 continue;
1766
1767 if (!legal_artifact_combination (op, art))
1768 {
1769 #ifdef TREASURE_VERBOSE
1770 LOG (llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name);
1771 #endif
1772 continue;
1773 }
1774 give_artifact_abilities (op, art->item);
1775 return;
1776 }
1777 }
1778
1779 /* fix_flesh_item() - objects of type FLESH are similar to type
1780 * FOOD, except they inherit properties (name, food value, etc).
1781 * based on the original owner (or 'donor' if you like). -b.t.
1782 */
1783
1784 void
1785 fix_flesh_item (object *item, object *donor)
1786 {
1787 char tmpbuf[MAX_BUF];
1788 int i;
1789
1790 if (item->type == FLESH && donor)
1791 {
1792 /* change the name */
1793 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name);
1794 item->name = tmpbuf;
1795 sprintf (tmpbuf, "%s's %s", &donor->name, &item->name_pl);
1796 item->name_pl = tmpbuf;
1797
1798 /* weight is FLESH weight/100 * donor */
1799 if ((item->weight = (signed long) (((double) item->weight / (double) 100.0) * (double) donor->weight)) == 0)
1800 item->weight = 1;
1801
1802 /* value is multiplied by level of donor */
1803 item->value *= isqrt (donor->level * 2);
1804
1805 /* food value */
1806 item->stats.food += (donor->stats.hp / 100) + donor->stats.Con;
1807
1808 /* flesh items inherit some abilities of donor, but not
1809 * full effect.
1810 */
1811 for (i = 0; i < NROFATTACKS; i++)
1812 item->resist[i] = donor->resist[i] / 2;
1813
1814 /* item inherits donor's level (important for quezals) */
1815 item->level = donor->level;
1816
1817 /* if donor has some attacktypes, the flesh is poisonous */
1818 if (donor->attacktype & AT_POISON)
1819 item->type = POISON;
1820 if (donor->attacktype & AT_ACID)
1821 item->stats.hp = -1 * item->stats.food;
1822 SET_FLAG (item, FLAG_NO_STEAL);
1823 }
1824 }
1825
1826 /* special_potion() - so that old potion code is still done right. */
1827
1828 int
1829 special_potion (object *op)
1830 {
1831 if (op->attacktype)
1832 return 1;
1833
1834 if (op->stats.Str || op->stats.Dex || op->stats.Con || op->stats.Pow || op->stats.Wis || op->stats.Int || op->stats.Cha)
1835 return 1;
1836
1837 for (int i = 0; i < NROFATTACKS; i++)
1838 if (op->resist[i])
1839 return 1;
1840
1841 return 0;
1842 }
1843
1844 void
1845 free_treasurestruct (treasure *t)
1846 {
1847 if (t->next)
1848 free_treasurestruct (t->next);
1849 if (t->next_yes)
1850 free_treasurestruct (t->next_yes);
1851 if (t->next_no)
1852 free_treasurestruct (t->next_no);
1853
1854 delete t;
1855 }
1856
1857 void
1858 free_charlinks (linked_char *lc)
1859 {
1860 if (lc->next)
1861 free_charlinks (lc->next);
1862
1863 delete lc;
1864 }
1865
1866 void
1867 free_artifact (artifact * at)
1868 {
1869 if (at->next)
1870 free_artifact (at->next);
1871
1872 if (at->allowed)
1873 free_charlinks (at->allowed);
1874
1875 at->item->destroy (1);
1876
1877 delete at;
1878 }
1879
1880 void
1881 free_artifactlist (artifactlist * al)
1882 {
1883 artifactlist *nextal;
1884
1885 for (al = first_artifactlist; al; al = nextal)
1886 {
1887 nextal = al->next;
1888
1889 if (al->items)
1890 free_artifact (al->items);
1891
1892 free (al);
1893 }
1894 }
1895
1896 void
1897 free_all_treasures (void)
1898 {
1899 treasurelist *tl, *next;
1900
1901
1902 for (tl = first_treasurelist; tl != NULL; tl = next)
1903 {
1904 next = tl->next;
1905 if (tl->items)
1906 free_treasurestruct (tl->items);
1907 delete tl;
1908 }
1909 free_artifactlist (first_artifactlist);
1910 }