ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/treasure.C
Revision: 1.30
Committed: Wed Jan 3 02:30:51 2007 UTC (17 years, 4 months ago) by elmex
Content type: text/plain
Branch: MAIN
Changes since 1.29: +33 -38 lines
Log Message:
implemented proper support for empty treasures, which
sadly occur in empty treasure lists. fixing treasurelists
to have no entries at all would be even more complicated,
but even when this is fixed, the current changes only make the
server more crash robust to bad treasures.
Also removed the 'NONE' specialcase for treasure lists. Developers
should use 'none' instead now.

File Contents

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