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

# User Rev Content
1 elmex 1.1 /*
2 pippijn 1.32 * 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 elmex 1.1
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 root 1.16
36 elmex 1.1 /* #define TREASURE_VERBOSE */
37 root 1.7
38 elmex 1.1 #include <global.h>
39     #include <treasure.h>
40     #include <funcpoint.h>
41     #include <loader.h>
42    
43    
44 root 1.16 static void change_treasure (treasure *t, object *op); /* overrule default values */
45 elmex 1.1 extern char *spell_mapping[];
46    
47     /*
48     * Initialize global archtype pointers:
49     */
50    
51 root 1.7 void
52     init_archetype_pointers ()
53     {
54 elmex 1.1 int prev_warn = warn_archetypes;
55 root 1.16
56 elmex 1.1 warn_archetypes = 1;
57     if (ring_arch == NULL)
58 root 1.18 ring_arch = archetype::find ("ring");
59 elmex 1.1 if (amulet_arch == NULL)
60 root 1.18 amulet_arch = archetype::find ("amulet");
61 elmex 1.1 if (staff_arch == NULL)
62 root 1.18 staff_arch = archetype::find ("staff");
63 elmex 1.1 if (crown_arch == NULL)
64 root 1.18 crown_arch = archetype::find ("crown");
65 elmex 1.1 warn_archetypes = prev_warn;
66     }
67    
68     /*
69     * Allocate and return the pointer to an empty treasurelist structure.
70     */
71    
72 root 1.7 static treasurelist *
73     get_empty_treasurelist (void)
74     {
75     return new treasurelist;
76 elmex 1.1 }
77    
78     /*
79     * Allocate and return the pointer to an empty treasure structure.
80     */
81 root 1.7 //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 elmex 1.1
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 root 1.7 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 root 1.16 continue;
111 root 1.7 if ((cp = strchr (buf, '\n')) != NULL)
112 root 1.16 *cp = '\0';
113 root 1.7 cp = buf;
114 root 1.16 while (isspace (*cp)) /* Skip blanks */
115     cp++;
116 root 1.7
117     if (sscanf (cp, "arch %s", variable))
118 root 1.16 {
119 root 1.18 if ((t->item = archetype::find (variable)) == NULL)
120 root 1.16 LOG (llevError, "Treasure lacks archetype: %s\n", variable);
121     }
122 root 1.7 else if (sscanf (cp, "list %s", variable))
123 elmex 1.9 t->name = variable;
124 root 1.7 else if (sscanf (cp, "change_name %s", variable))
125 root 1.16 t->change_arch.name = variable;
126 root 1.7 else if (sscanf (cp, "change_title %s", variable))
127 root 1.16 t->change_arch.title = variable;
128 root 1.7 else if (sscanf (cp, "change_slaying %s", variable))
129 root 1.16 t->change_arch.slaying = variable;
130 root 1.7 else if (sscanf (cp, "chance %d", &value))
131 root 1.16 t->chance = (uint8) value;
132 root 1.7 else if (sscanf (cp, "nrof %d", &value))
133 root 1.16 t->nrof = (uint16) value;
134 root 1.7 else if (sscanf (cp, "magic %d", &value))
135 root 1.16 t->magic = (uint8) value;
136 root 1.7 else if (!strcmp (cp, "yes"))
137 root 1.16 t->next_yes = load_treasure (fp, line);
138 root 1.7 else if (!strcmp (cp, "no"))
139 root 1.16 t->next_no = load_treasure (fp, line);
140 root 1.7 else if (!strcmp (cp, "end"))
141 root 1.16 return t;
142 root 1.7 else if (!strcmp (cp, "more"))
143 root 1.16 {
144     t->next = load_treasure (fp, line);
145     return t;
146     }
147 root 1.7 else
148 root 1.16 LOG (llevError, "Unknown treasure-command: '%s', last entry %s, line %d\n", cp, &t->name, *line);
149 elmex 1.1 }
150 root 1.7 LOG (llevError, "treasure lacks 'end'.\n");
151     return t;
152 elmex 1.1 }
153    
154     #ifdef TREASURE_DEBUG
155 root 1.16
156 elmex 1.1 /* recursived checks the linked list. Treasurelist is passed only
157     * so that the treasure name can be printed out
158     */
159 root 1.7 static void
160 root 1.16 check_treasurelist (const treasure *t, const treasurelist * tl)
161 elmex 1.1 {
162 root 1.7 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 elmex 1.30 find_treasurelist (t->name);
167 root 1.7 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 elmex 1.1 }
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 root 1.7 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 root 1.40 if (*buf == '#' || *buf == '\n')
200     ; // ignore
201     else 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 root 1.40
211 root 1.16 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 elmex 1.1 #ifdef TREASURE_DEBUG
223 root 1.16 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 elmex 1.1 #endif
229 root 1.16 tl->total_chance += t->chance;
230     }
231     }
232     }
233 root 1.7 else
234 root 1.16 LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line);
235 elmex 1.1 }
236 root 1.7 close_and_delete (fp, comp);
237 elmex 1.1
238     #ifdef TREASURE_DEBUG
239 root 1.7 /* 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 elmex 1.1 #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 root 1.7 treasurelist *
255     find_treasurelist (const char *name)
256     {
257 root 1.17 shstr_cmp name_ (name);
258    
259     if (!name_)
260 root 1.12 return 0;
261 root 1.7
262 elmex 1.26 for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next)
263 root 1.17 if (name_ == tl->name)
264     return tl;
265 elmex 1.9
266     if (first_treasurelist)
267 root 1.12 LOG (llevError, "Couldn't find treasurelist %s\n", name);
268 root 1.7
269 root 1.12 return 0;
270 elmex 1.1 }
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 root 1.7 static void
285 root 1.16 put_treasure (object *op, object *creator, int flags)
286 elmex 1.1 {
287 root 1.7 object *tmp;
288 elmex 1.1
289 root 1.7 /* 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 root 1.29 op->insert_at (creator, creator, INS_NO_MERGE | INS_NO_WALK_ON);
298 root 1.7 }
299     else
300     {
301 root 1.29 op = creator->insert (op);
302 root 1.27
303 root 1.7 if ((flags & GT_APPLY) && QUERY_FLAG (creator, FLAG_MONSTER))
304 root 1.16 monster_check_apply (creator, op);
305 root 1.27
306     if ((flags & GT_UPDATE_INV) && (tmp = creator->in_player ()))
307 root 1.16 esrv_send_item (tmp, op);
308 elmex 1.1 }
309     }
310    
311     /* if there are change_xxx commands in the treasure, we include the changes
312     * in the generated object
313     */
314 root 1.7 static void
315 root 1.12 change_treasure (treasure *t, object *op)
316 elmex 1.1 {
317 root 1.7 /* CMD: change_name xxxx */
318     if (t->change_arch.name)
319 elmex 1.1 {
320 root 1.7 op->name = t->change_arch.name;
321     op->name_pl = t->change_arch.name;
322 elmex 1.1 }
323    
324 root 1.7 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 root 1.12 create_all_treasures (treasure *t, object *op, int flag, int difficulty, int tries)
333 root 1.7 {
334     object *tmp;
335    
336 root 1.33 if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance)
337 elmex 1.1 {
338 root 1.7 if (t->name)
339 root 1.16 {
340 elmex 1.30 if (difficulty >= t->magic)
341 elmex 1.26 {
342     treasurelist *tl = find_treasurelist (t->name);
343     if (tl)
344     create_treasure (tl, op, flag, difficulty, tries);
345     }
346 root 1.16 }
347 root 1.7 else
348 root 1.16 {
349 elmex 1.30 if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE)))
350 root 1.16 {
351     tmp = arch_to_object (t->item);
352     if (t->nrof && tmp->nrof <= 1)
353 root 1.35 tmp->nrof = rndm (t->nrof) + 1;
354    
355 root 1.16 fix_generated_item (tmp, op, difficulty, t->magic, flag);
356     change_treasure (t, tmp);
357     put_treasure (tmp, op, flag);
358     }
359     }
360 root 1.12
361 root 1.7 if (t->next_yes != NULL)
362 root 1.16 create_all_treasures (t->next_yes, op, flag, difficulty, tries);
363 elmex 1.1 }
364 root 1.7 else if (t->next_no != NULL)
365     create_all_treasures (t->next_no, op, flag, difficulty, tries);
366 root 1.12
367 root 1.7 if (t->next != NULL)
368     create_all_treasures (t->next, op, flag, difficulty, tries);
369 elmex 1.1 }
370    
371 root 1.7 void
372 root 1.35 create_one_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries)
373 root 1.7 {
374 root 1.35 int value = rndm (tl->total_chance);
375 root 1.7 treasure *t;
376 elmex 1.1
377 root 1.7 if (tries++ > 100)
378     {
379     LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n");
380     return;
381     }
382 root 1.12
383 root 1.7 for (t = tl->items; t != NULL; t = t->next)
384     {
385     value -= t->chance;
386 root 1.12
387 root 1.7 if (value < 0)
388 root 1.16 break;
389 root 1.7 }
390 elmex 1.1
391 root 1.7 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 root 1.12
398 root 1.7 if (t->name)
399     {
400     if (difficulty >= t->magic)
401 elmex 1.26 {
402     treasurelist *tl = find_treasurelist (t->name);
403     if (tl)
404     create_treasure (tl, op, flag, difficulty, tries);
405     }
406 root 1.7 else if (t->nrof)
407 root 1.16 create_one_treasure (tl, op, flag, difficulty, tries);
408 root 1.12
409 root 1.7 return;
410 elmex 1.1 }
411 root 1.12
412 elmex 1.30 if (t->item && (t->item->clone.invisible != 0 || flag != GT_INVISIBLE))
413 root 1.7 {
414     object *tmp = arch_to_object (t->item);
415 root 1.12
416 root 1.7 if (!tmp)
417 root 1.16 return;
418 root 1.12
419 root 1.7 if (t->nrof && tmp->nrof <= 1)
420 root 1.35 tmp->nrof = rndm (t->nrof) + 1;
421 root 1.12
422 root 1.13 fix_generated_item (tmp, op, difficulty, t->magic, flag);
423     change_treasure (t, tmp);
424 root 1.7 put_treasure (tmp, op, flag);
425 elmex 1.1 }
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 root 1.7 void
436 elmex 1.30 create_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries)
437 elmex 1.1 {
438 root 1.7 if (tries++ > 100)
439     {
440     LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n");
441     return;
442     }
443 root 1.37
444 elmex 1.30 if (tl->total_chance)
445     create_one_treasure (tl, op, flag, difficulty, tries);
446 root 1.7 else
447 elmex 1.30 create_all_treasures (tl->items, op, flag, difficulty, tries);
448 elmex 1.1 }
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 root 1.7 object *
456 elmex 1.30 generate_treasure (treasurelist *tl, int difficulty)
457 elmex 1.1 {
458 root 1.25 difficulty = clamp (difficulty, 1, settings.max_level);
459    
460 root 1.24 object *ob = object::create (), *tmp;
461 elmex 1.1
462 elmex 1.30 create_treasure (tl, ob, 0, difficulty, 0);
463 elmex 1.1
464 root 1.7 /* Don't want to free the object we are about to return */
465     tmp = ob->inv;
466     if (tmp != NULL)
467 root 1.23 tmp->remove ();
468 root 1.21
469 root 1.7 if (ob->inv)
470 root 1.21 LOG (llevError, "In generate treasure, created multiple objects.\n");
471    
472 root 1.24 ob->destroy ();
473 root 1.7 return tmp;
474 elmex 1.1 }
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 root 1.7 static int difftomagic_list[DIFFLEVELS][MAXMAGIC + 1] = {
484 root 1.16
485 elmex 1.1 /*chance of magic difficulty*/
486 root 1.16
487 elmex 1.1 /* +0 +1 +2 +3 +4 */
488 root 1.16 {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 elmex 1.1 };
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 root 1.7 int
530 root 1.16 level_for_item (const object *op, int difficulty)
531 elmex 1.1 {
532 pippijn 1.14 int olevel = 0;
533 elmex 1.1
534     if (!op->inv)
535     {
536 root 1.7 LOG (llevError, "level_for_item: Object %s has no inventory!\n", &op->name);
537     return 0;
538 elmex 1.1 }
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 root 1.7 int
563     magic_from_difficulty (int difficulty)
564 elmex 1.1 {
565     int percent = 0, magic = 0;
566     int scaled_diff = (int) (((double) difficulty / settings.max_level) * DIFFLEVELS);
567    
568     scaled_diff--;
569    
570 root 1.7 if (scaled_diff < 0)
571 elmex 1.1 scaled_diff = 0;
572    
573     if (scaled_diff >= DIFFLEVELS)
574 root 1.7 scaled_diff = DIFFLEVELS - 1;
575 elmex 1.1
576 root 1.33 percent = rndm (100);
577 elmex 1.1
578 root 1.7 for (magic = 0; magic < (MAXMAGIC + 1); magic++)
579 elmex 1.1 {
580     percent -= difftomagic_list[scaled_diff][magic];
581    
582     if (percent < 0)
583 root 1.16 break;
584 elmex 1.1 }
585    
586     if (magic == (MAXMAGIC + 1))
587     {
588 root 1.7 LOG (llevError, "Warning, table for difficulty (scaled %d) %d bad.\n", scaled_diff, difficulty);
589 elmex 1.1 magic = 0;
590     }
591    
592 root 1.33 magic = (rndm (3)) ? magic : -magic;
593 elmex 1.1 /* 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 root 1.7 void
606 root 1.16 set_abs_magic (object *op, int magic)
607 root 1.7 {
608     if (!magic)
609 elmex 1.1 return;
610    
611 root 1.7 op->magic = magic;
612     if (op->arch)
613     {
614     if (op->type == ARMOUR)
615 root 1.16 ARMOUR_SPEED (op) = (ARMOUR_SPEED (&op->arch->clone) * (100 + magic * 10)) / 100;
616 root 1.7
617 root 1.33 if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */
618 root 1.16 magic = (-magic);
619 root 1.7 op->weight = (op->arch->clone.weight * (100 - magic * 10)) / 100;
620     }
621     else
622     {
623     if (op->type == ARMOUR)
624 root 1.16 ARMOUR_SPEED (op) = (ARMOUR_SPEED (op) * (100 + magic * 10)) / 100;
625 root 1.33 if (magic < 0 && !(rndm (3))) /* You can't just check the weight always */
626 root 1.16 magic = (-magic);
627 root 1.7 op->weight = (op->weight * (100 - magic * 10)) / 100;
628     }
629 elmex 1.1 }
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 root 1.7 static void
637 root 1.16 set_magic (int difficulty, object *op, int max_magic, int flags)
638 elmex 1.1 {
639     int i;
640 root 1.16
641 root 1.7 i = magic_from_difficulty (difficulty);
642 elmex 1.1 if ((flags & GT_ONLY_GOOD) && i < 0)
643 root 1.7 i = -i;
644     if (i > max_magic)
645 elmex 1.1 i = max_magic;
646 root 1.7 set_abs_magic (op, i);
647 elmex 1.1 if (i < 0)
648 root 1.7 SET_FLAG (op, FLAG_CURSED);
649 elmex 1.1 }
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 root 1.7 void
661 root 1.16 set_ring_bonus (object *op, int bonus)
662 root 1.7 {
663 elmex 1.1
664 root 1.35 int r = rndm (bonus > 0 ? 25 : 11);
665 elmex 1.1
666 root 1.7 if (op->type == AMULET)
667     {
668 root 1.33 if (!(rndm (21)))
669     r = 20 + rndm (2);
670 root 1.7 else
671 root 1.16 {
672 root 1.35 if (rndm (2))
673 root 1.16 r = 10;
674     else
675 root 1.33 r = 11 + rndm (9);
676 root 1.16 }
677 root 1.7 }
678    
679     switch (r)
680     {
681 root 1.16 /* 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 root 1.34 int b = 5 + abs (bonus), val, resist = rndm (num_resist_table);
723 root 1.16
724     /* Roughly generate a bonus between 100 and 35 (depending on the bonus) */
725 root 1.34 val = 10 + rndm (b) + rndm (b) + rndm (b) + rndm (b);
726 root 1.16
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 root 1.35 val = 2 * -val - rndm (b);
734 root 1.16 if (val > 35)
735     val = 35; /* Upper limit */
736     b = 0;
737 root 1.34
738 root 1.16 while (op->resist[resist_table[resist]] != 0 && b < 4)
739 root 1.34 resist = rndm (num_resist_table);
740    
741 root 1.16 if (b == 4)
742     return; /* Not able to find a free resistance */
743 root 1.34
744 root 1.16 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 root 1.7 }
781 root 1.34
782 root 1.7 if (bonus > 0)
783     op->value *= 2 * bonus;
784     else
785     op->value = -(op->value * 2 * bonus) / 3;
786 elmex 1.1 }
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 root 1.7 int
797     get_magic (int diff)
798     {
799 elmex 1.1 int i;
800 root 1.16
801 root 1.7 if (diff < 3)
802     diff = 3;
803 root 1.35
804 root 1.7 for (i = 0; i < 4; i++)
805 root 1.35 if (rndm (diff))
806 root 1.7 return i;
807 root 1.35
808 elmex 1.1 return 4;
809     }
810    
811     #define DICE2 (get_magic(2)==2?2:1)
812 root 1.35 #define DICESPELL (rndm (3) + rndm (3) + rndm (3) + rndm (3) + rndm (3))
813 elmex 1.1
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 root 1.16
820 elmex 1.1 /* 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 root 1.16
825 elmex 1.1 /*
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 root 1.7 void
837 root 1.16 fix_generated_item (object *op, object *creator, int difficulty, int max_magic, int flags)
838 elmex 1.1 {
839     int was_magic = op->magic, num_enchantments = 0, save_item_power = 0;
840    
841     if (!creator || creator->type == op->type)
842 root 1.16 creator = op; /*safety & to prevent polymorphed objects giving attributes */
843 elmex 1.1
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 root 1.16 LOG (llevDebug, "fix_generated_item: Unable to generate treasure for %s\n", &op->name);
853 elmex 1.1
854     /* So the treasure doesn't get created again */
855     op->randomitems = NULL;
856     }
857    
858     if (difficulty < 1)
859     difficulty = 1;
860    
861 root 1.22 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 elmex 1.1 if (!(flags & GT_MINIMAL))
868     {
869     if (op->arch == crown_arch)
870 root 1.16 {
871     set_magic (difficulty, op, max_magic, flags);
872     num_enchantments = calc_item_power (op, 1);
873     generate_artifact (op, difficulty);
874     }
875 elmex 1.1 else
876 root 1.16 {
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 root 1.35 if ((!was_magic && !rndm (CHANCE_FOR_ARTIFACT))
883     || op->type == HORN
884     || difficulty >= settings.max_level) /* high difficulties always generate an artifact,
885 root 1.16 * used for shop_floors or treasures */
886     generate_artifact (op, difficulty);
887     }
888 elmex 1.1
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 root 1.16 {
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 elmex 1.1 else if (save_item_power)
907 root 1.16 {
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 elmex 1.1 else
915 root 1.16 {
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 elmex 1.1 }
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 root 1.16 /* 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 elmex 1.1 }
944 root 1.16 else if (!op->title) /* Only modify object if not special */
945 elmex 1.1 switch (op->type)
946     {
947 root 1.16 case WEAPON:
948     case ARMOUR:
949     case SHIELD:
950     case HELMET:
951     case CLOAK:
952 root 1.33 if (QUERY_FLAG (op, FLAG_CURSED) && !(rndm (4)))
953 root 1.16 set_ring_bonus (op, -DICE2);
954     break;
955    
956     case BRACERS:
957 root 1.35 if (!rndm (QUERY_FLAG (op, FLAG_CURSED) ? 5 : 20))
958 root 1.16 {
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 root 1.35 op->level = op->inv->level / 2 + rndm (difficulty) + rndm (difficulty);
994 root 1.16 }
995     else
996     {
997     op->name = "potion";
998     op->name_pl = "potions";
999     }
1000    
1001 root 1.33 if (!(flags & GT_ONLY_GOOD) && rndm (2))
1002 root 1.16 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 root 1.24 op->destroy ();
1014     op = 0;
1015 root 1.16 break;
1016     }
1017    
1018     if (op->arch != ring_arch && op->arch != amulet_arch) /* It's a special artifact! */
1019     break;
1020    
1021 root 1.33 if (!(flags & GT_ONLY_GOOD) && !(rndm (3)))
1022 root 1.16 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 root 1.33 if (!(rndm (4)))
1030 root 1.16 {
1031 root 1.33 int d = (rndm (2) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1032 root 1.16
1033     if (d > 0)
1034     op->value *= 3;
1035    
1036     set_ring_bonus (op, d);
1037    
1038 root 1.33 if (!(rndm (4)))
1039 root 1.16 {
1040 root 1.33 int d = (rndm (3) || QUERY_FLAG (op, FLAG_CURSED)) ? -DICE2 : DICE2;
1041 root 1.16
1042     if (d > 0)
1043     op->value *= 5;
1044     set_ring_bonus (op, d);
1045     }
1046     }
1047    
1048     if (GET_ANIM_ID (op))
1049 root 1.35 SET_ANIMATION (op, rndm (NUM_ANIMATIONS (op)));
1050 root 1.16
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 root 1.33 if (!op->msg && rndm (10))
1059 root 1.16 {
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 root 1.35 op->level = rndm (op->map->difficulty) + rndm (10) + 1;
1065 root 1.16 else
1066 root 1.33 op->level = rndm (20) + 1;
1067 root 1.16 }
1068     else
1069 root 1.35 op->level = rndm (creator->level);
1070 root 1.16
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 elmex 1.1
1155     if (flags & GT_STARTEQUIP)
1156     {
1157 root 1.7 if (op->nrof < 2 && op->type != CONTAINER && op->type != MONEY && !QUERY_FLAG (op, FLAG_IS_THROWN))
1158 root 1.16 SET_FLAG (op, FLAG_STARTEQUIP);
1159 elmex 1.1 else if (op->type != MONEY)
1160 root 1.16 op->value = 0;
1161 elmex 1.1 }
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 root 1.7 static artifactlist *
1179     get_empty_artifactlist (void)
1180     {
1181 elmex 1.30 artifactlist *al = (artifactlist *) malloc (sizeof (artifactlist));
1182 root 1.16
1183 elmex 1.30 if (al == NULL)
1184 root 1.7 fatal (OUT_OF_MEMORY);
1185 elmex 1.30 al->next = NULL;
1186     al->items = NULL;
1187     al->total_chance = 0;
1188     return al;
1189 elmex 1.1 }
1190    
1191     /*
1192     * Allocate and return the pointer to an empty artifact structure.
1193     */
1194 root 1.7 static artifact *
1195     get_empty_artifact (void)
1196     {
1197 elmex 1.30 artifact *a = (artifact *) malloc (sizeof (artifact));
1198 root 1.16
1199 elmex 1.30 if (a == NULL)
1200 root 1.7 fatal (OUT_OF_MEMORY);
1201 root 1.38
1202 elmex 1.30 a->item = NULL;
1203     a->next = NULL;
1204     a->chance = 0;
1205     a->difficulty = 0;
1206     a->allowed = NULL;
1207     return a;
1208 elmex 1.1 }
1209    
1210     /*
1211     * Searches the artifact lists and returns one that has the same type
1212     * of objects on it.
1213     */
1214 root 1.7 artifactlist *
1215     find_artifactlist (int type)
1216     {
1217 elmex 1.1 artifactlist *al;
1218    
1219 root 1.38 for (al = first_artifactlist; al; al = al->next)
1220 root 1.7 if (al->type == type)
1221     return al;
1222 root 1.38
1223     return 0;
1224 elmex 1.1 }
1225    
1226     /*
1227     * For debugging purposes. Dumps all tables.
1228     */
1229 root 1.7 void
1230     dump_artifacts (void)
1231     {
1232 elmex 1.1 artifactlist *al;
1233     artifact *art;
1234     linked_char *next;
1235    
1236 root 1.7 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 root 1.16 {
1242     fprintf (logfile, "Artifact %-30s Difficulty %3d Chance %5d\n", &art->item->name, art->difficulty, art->chance);
1243     if (art->allowed != NULL)
1244     {
1245 root 1.38 fprintf (logfile, "\tallowed combinations:");
1246 root 1.16 for (next = art->allowed; next != NULL; next = next->next)
1247     fprintf (logfile, "%s,", &next->name);
1248     fprintf (logfile, "\n");
1249     }
1250     }
1251 elmex 1.1 }
1252 root 1.7 fprintf (logfile, "\n");
1253 elmex 1.1 }
1254    
1255     /*
1256     * For debugging purposes. Dumps all treasures recursively (see below).
1257     */
1258 root 1.7 void
1259 root 1.16 dump_monster_treasure_rec (const char *name, treasure *t, int depth)
1260 elmex 1.1 {
1261     treasurelist *tl;
1262 root 1.7 int i;
1263 elmex 1.1
1264     if (depth > 100)
1265     return;
1266 elmex 1.30 while (t)
1267 elmex 1.1 {
1268 elmex 1.30 if (t->name)
1269 root 1.16 {
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 elmex 1.26 if (tl)
1275     dump_monster_treasure_rec (name, tl->items, depth + 2);
1276 root 1.16 for (i = 0; i < depth; i++)
1277     fprintf (logfile, " ");
1278     fprintf (logfile, "} (end of list: %s)\n", &t->name);
1279     }
1280 elmex 1.1 else
1281 root 1.16 {
1282     for (i = 0; i < depth; i++)
1283     fprintf (logfile, " ");
1284 elmex 1.30 if (t->item && t->item->clone.type == FLESH)
1285 root 1.16 fprintf (logfile, "%s's %s\n", name, &t->item->clone.name);
1286     else
1287     fprintf (logfile, "%s\n", &t->item->clone.name);
1288     }
1289 elmex 1.30
1290     if (t->next_yes)
1291 root 1.16 {
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 elmex 1.30
1298     if (t->next_no)
1299 root 1.16 {
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 elmex 1.30
1306 elmex 1.1 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 root 1.7 void
1316     dump_monster_treasure (const char *name)
1317 elmex 1.1 {
1318     archetype *at;
1319 root 1.7 int found;
1320 elmex 1.1
1321     found = 0;
1322     fprintf (logfile, "\n");
1323 root 1.38
1324 root 1.7 for (at = first_archetype; at != NULL; at = at->next)
1325     if (!strcasecmp (at->clone.name, name) && at->clone.title == NULL)
1326 elmex 1.1 {
1327 root 1.16 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 root 1.38
1333 root 1.16 fprintf (logfile, "\n");
1334     found++;
1335 elmex 1.1 }
1336 root 1.38
1337 elmex 1.1 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 root 1.7 void
1345     init_artifacts (void)
1346     {
1347     static int has_been_inited = 0;
1348 pippijn 1.39 char filename[MAX_BUF];
1349 root 1.7 artifact *art = NULL;
1350     artifactlist *al;
1351    
1352     if (has_been_inited)
1353     return;
1354     else
1355     has_been_inited = 1;
1356 elmex 1.1
1357 root 1.7 sprintf (filename, "%s/artifacts", settings.datadir);
1358 root 1.38 object_thawer f (filename);
1359 elmex 1.1
1360 root 1.38 if (!f)
1361 root 1.7 return;
1362 elmex 1.1
1363 root 1.38 f.next ();
1364    
1365     for (;;)
1366 root 1.7 {
1367 root 1.38 switch (f.kw)
1368     {
1369     case KW_allowed:
1370     if (!art)
1371     {
1372     art = get_empty_artifact ();
1373     nrofartifacts++;
1374     }
1375 root 1.7
1376 root 1.16 {
1377 root 1.38 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 root 1.16 }
1397 root 1.38 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 root 1.16
1407 root 1.38 case KW_object:
1408 root 1.16 {
1409 root 1.38 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 root 1.16 }
1428 root 1.38 continue;
1429 root 1.10
1430 root 1.38 case KW_EOF:
1431     goto done;
1432 root 1.10
1433 root 1.38 default:
1434     if (!f.parse_error ("artifacts file"))
1435     cleanup ("artifacts file required");
1436     break;
1437 root 1.16 }
1438 root 1.38
1439     f.next ();
1440 root 1.7 }
1441 root 1.3
1442 root 1.38 done:
1443     for (al = first_artifactlist; al; al = al->next)
1444 root 1.7 {
1445 root 1.38 for (art = al->items; art; art = art->next)
1446 root 1.16 {
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 elmex 1.1 #if 0
1453 root 1.7 LOG (llevDebug, "Artifact list type %d has %d total chance\n", al->type, al->total_chance);
1454 elmex 1.1 #endif
1455     }
1456    
1457 root 1.7 LOG (llevDebug, "done.\n");
1458 elmex 1.1 }
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 root 1.7 void
1467 root 1.16 add_abilities (object *op, object *change)
1468 root 1.7 {
1469 pippijn 1.14 int i, tmp;
1470 elmex 1.1
1471 root 1.7 if (change->face != blank_face)
1472     {
1473 elmex 1.1 #ifdef TREASURE_VERBOSE
1474 root 1.7 LOG (llevDebug, "FACE: %d\n", change->face->number);
1475 elmex 1.1 #endif
1476 root 1.7 op->face = change->face;
1477 elmex 1.1 }
1478    
1479 root 1.7 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 root 1.16 op->speed = 0.0;
1519 root 1.12
1520 root 1.28 op->set_speed (op->speed);
1521 elmex 1.1 }
1522 root 1.7
1523     if (change->nrof)
1524 root 1.35 op->nrof = rndm (change->nrof) + 1;
1525 root 1.7
1526 root 1.16 op->stats.exp += change->stats.exp; /* Speed modifier */
1527 root 1.7 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 root 1.16 {
1538     object *tmp_obj;
1539    
1540     /* Remove any spells this object currently has in it */
1541     while (op->inv)
1542 root 1.24 op->inv->destroy ();
1543 root 1.16
1544     tmp_obj = arch_to_object (change->other_arch);
1545     insert_ob_in_ob (tmp_obj, op);
1546     }
1547 root 1.7 /* 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 root 1.20 if (change->resist[i])
1590     op->resist[i] += change->resist[i];
1591 root 1.7
1592     if (change->stats.dam)
1593     {
1594     if (change->stats.dam < 0)
1595 root 1.16 op->stats.dam = (-change->stats.dam);
1596 root 1.7 else if (op->stats.dam)
1597 root 1.16 {
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 root 1.7 }
1610    
1611     if (change->weight)
1612     {
1613     if (change->weight < 0)
1614 root 1.16 op->weight = (-change->weight);
1615 root 1.7 else
1616 root 1.16 op->weight = (op->weight * (change->weight)) / 100;
1617 root 1.7 }
1618    
1619     if (change->last_sp)
1620     {
1621     if (change->last_sp < 0)
1622 root 1.16 op->last_sp = (-change->last_sp);
1623 root 1.7 else
1624 root 1.16 op->last_sp = (signed char) (((int) op->last_sp * (int) change->last_sp) / (int) 100);
1625 root 1.7 }
1626    
1627     if (change->gen_sp_armour)
1628     {
1629     if (change->gen_sp_armour < 0)
1630 root 1.16 op->gen_sp_armour = (-change->gen_sp_armour);
1631 root 1.7 else
1632 root 1.16 op->gen_sp_armour = (signed char) (((int) op->gen_sp_armour * ((int) change->gen_sp_armour)) / (int) 100);
1633 root 1.7 }
1634    
1635     op->value *= change->value;
1636    
1637 root 1.36 if (change->materials)
1638     op->materials = change->materials;
1639 root 1.7
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 elmex 1.1 }
1652    
1653 root 1.7 static int
1654 root 1.16 legal_artifact_combination (object *op, artifact * art)
1655 root 1.7 {
1656 elmex 1.1 int neg, success = 0;
1657     linked_char *tmp;
1658     const char *name;
1659    
1660     if (art->allowed == (linked_char *) NULL)
1661 root 1.16 return 1; /* Ie, "all" */
1662 root 1.7 for (tmp = art->allowed; tmp; tmp = tmp->next)
1663     {
1664 elmex 1.1 #ifdef TREASURE_VERBOSE
1665 root 1.7 LOG (llevDebug, "legal_art: %s\n", tmp->name);
1666 elmex 1.1 #endif
1667 root 1.7 if (*tmp->name == '!')
1668 root 1.16 name = tmp->name + 1, neg = 1;
1669 root 1.7 else
1670 root 1.16 name = tmp->name, neg = 0;
1671 root 1.7
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 root 1.16 return !neg;
1675 root 1.7
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 root 1.16 success = 1;
1681 root 1.7 }
1682 elmex 1.1 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 root 1.7 void
1691 root 1.12 give_artifact_abilities (object *op, object *artifct)
1692 root 1.7 {
1693 elmex 1.1 char new_name[MAX_BUF];
1694    
1695 root 1.7 sprintf (new_name, "of %s", &artifct->name);
1696     op->title = new_name;
1697 root 1.16 add_abilities (op, artifct); /* Give out the bonuses */
1698 elmex 1.1
1699 root 1.16 #if 0 /* Bit verbose, but keep it here until next time I need it... */
1700 elmex 1.1 {
1701 root 1.7 char identified = QUERY_FLAG (op, FLAG_IDENTIFIED);
1702 root 1.16
1703 root 1.7 SET_FLAG (op, FLAG_IDENTIFIED);
1704     LOG (llevDebug, "Generated artifact %s %s [%s]\n", op->name, op->title, describe_item (op, NULL));
1705 elmex 1.1 if (!identified)
1706 root 1.7 CLEAR_FLAG (op, FLAG_IDENTIFIED);
1707 elmex 1.1 }
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 root 1.7 void
1724 root 1.16 generate_artifact (object *op, int difficulty)
1725 root 1.7 {
1726 elmex 1.1 artifactlist *al;
1727     artifact *art;
1728     int i;
1729    
1730 root 1.7 al = find_artifactlist (op->type);
1731    
1732     if (al == NULL)
1733     {
1734 root 1.16 #if 0 /* This is too verbose, usually */
1735 root 1.7 LOG (llevDebug, "Couldn't change %s into artifact - no table.\n", op->name);
1736 elmex 1.1 #endif
1737 root 1.7 return;
1738     }
1739    
1740     for (i = 0; i < ARTIFACT_TRIES; i++)
1741     {
1742 root 1.35 int roll = rndm (al->total_chance);
1743 elmex 1.1
1744 root 1.35 for (art = al->items; art; art = art->next)
1745 root 1.16 {
1746     roll -= art->chance;
1747     if (roll < 0)
1748     break;
1749     }
1750 elmex 1.1
1751 root 1.7 if (art == NULL || roll >= 0)
1752 root 1.16 {
1753 elmex 1.1 #if 1
1754 root 1.16 LOG (llevError, "Got null entry and non zero roll in generate_artifact, type %d\n", op->type);
1755 elmex 1.1 #endif
1756 root 1.16 return;
1757     }
1758 root 1.7 if (!strcmp (art->item->name, "NONE"))
1759 root 1.16 return;
1760 root 1.7 if (FABS (op->magic) < art->item->magic)
1761 root 1.16 continue; /* Not magic enough to be this item */
1762 root 1.7
1763     /* Map difficulty not high enough */
1764     if (difficulty < art->difficulty)
1765 root 1.16 continue;
1766 elmex 1.1
1767 root 1.7 if (!legal_artifact_combination (op, art))
1768 root 1.16 {
1769 elmex 1.1 #ifdef TREASURE_VERBOSE
1770 root 1.16 LOG (llevDebug, "%s of %s was not a legal combination.\n", op->name, art->item->name);
1771 elmex 1.1 #endif
1772 root 1.16 continue;
1773     }
1774 root 1.7 give_artifact_abilities (op, art->item);
1775     return;
1776 elmex 1.1 }
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 root 1.7 void
1785 root 1.16 fix_flesh_item (object *item, object *donor)
1786 root 1.7 {
1787     char tmpbuf[MAX_BUF];
1788     int i;
1789    
1790     if (item->type == FLESH && donor)
1791     {
1792     /* change the name */
1793 root 1.16 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 root 1.7
1798     /* weight is FLESH weight/100 * donor */
1799     if ((item->weight = (signed long) (((double) item->weight / (double) 100.0) * (double) donor->weight)) == 0)
1800 root 1.16 item->weight = 1;
1801 root 1.7
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 root 1.16 item->resist[i] = donor->resist[i] / 2;
1813 root 1.7
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 root 1.16 item->type = POISON;
1820 root 1.7 if (donor->attacktype & AT_ACID)
1821 root 1.16 item->stats.hp = -1 * item->stats.food;
1822 root 1.7 SET_FLAG (item, FLAG_NO_STEAL);
1823 elmex 1.1 }
1824     }
1825    
1826     /* special_potion() - so that old potion code is still done right. */
1827    
1828 root 1.7 int
1829 root 1.16 special_potion (object *op)
1830 root 1.7 {
1831     if (op->attacktype)
1832     return 1;
1833 elmex 1.1
1834 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)
1835     return 1;
1836 elmex 1.1
1837 elmex 1.30 for (int i = 0; i < NROFATTACKS; i++)
1838 root 1.7 if (op->resist[i])
1839     return 1;
1840 elmex 1.1
1841 root 1.7 return 0;
1842 elmex 1.1 }
1843    
1844 root 1.7 void
1845 root 1.16 free_treasurestruct (treasure *t)
1846 elmex 1.1 {
1847 root 1.7 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 root 1.8
1854     delete t;
1855 elmex 1.1 }
1856    
1857 root 1.7 void
1858 root 1.16 free_charlinks (linked_char *lc)
1859 elmex 1.1 {
1860 root 1.7 if (lc->next)
1861     free_charlinks (lc->next);
1862    
1863     delete lc;
1864 elmex 1.1 }
1865    
1866 root 1.7 void
1867     free_artifact (artifact * at)
1868 elmex 1.1 {
1869 root 1.7 if (at->next)
1870     free_artifact (at->next);
1871 root 1.15
1872 root 1.7 if (at->allowed)
1873     free_charlinks (at->allowed);
1874    
1875 root 1.21 at->item->destroy (1);
1876 root 1.7
1877     delete at;
1878 elmex 1.1 }
1879    
1880 root 1.7 void
1881     free_artifactlist (artifactlist * al)
1882 elmex 1.1 {
1883 root 1.7 artifactlist *nextal;
1884 root 1.15
1885 root 1.21 for (al = first_artifactlist; al; al = nextal)
1886 root 1.7 {
1887     nextal = al->next;
1888 root 1.15
1889 root 1.7 if (al->items)
1890 root 1.16 free_artifact (al->items);
1891 root 1.15
1892 root 1.7 free (al);
1893 elmex 1.1 }
1894     }
1895    
1896 root 1.7 void
1897     free_all_treasures (void)
1898     {
1899     treasurelist *tl, *next;
1900 elmex 1.1
1901    
1902 root 1.7 for (tl = first_treasurelist; tl != NULL; tl = next)
1903     {
1904     next = tl->next;
1905     if (tl->items)
1906 root 1.16 free_treasurestruct (tl->items);
1907 root 1.7 delete tl;
1908 elmex 1.1 }
1909 root 1.7 free_artifactlist (first_artifactlist);
1910 elmex 1.1 }