ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/treasure.C
Revision: 1.64
Committed: Sun Jul 1 05:00:18 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.63: +11 -12 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

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