… | |
… | |
38 | #include <global.h> |
38 | #include <global.h> |
39 | #include <treasure.h> |
39 | #include <treasure.h> |
40 | #include <funcpoint.h> |
40 | #include <funcpoint.h> |
41 | #include <loader.h> |
41 | #include <loader.h> |
42 | |
42 | |
|
|
43 | extern char *spell_mapping[]; |
|
|
44 | |
|
|
45 | static treasurelist *first_treasurelist; |
43 | |
46 | |
44 | static void change_treasure (treasure *t, object *op); /* overrule default values */ |
47 | static void change_treasure (treasure *t, object *op); /* overrule default values */ |
45 | extern char *spell_mapping[]; |
48 | |
|
|
49 | typedef std::tr1::unordered_map< |
|
|
50 | const char *, |
|
|
51 | treasurelist *, |
|
|
52 | str_hash, |
|
|
53 | str_equal, |
|
|
54 | slice_allocator< std::pair<const char *const, treasurelist *> >, |
|
|
55 | true |
|
|
56 | > tl_map_t; |
|
|
57 | |
|
|
58 | static tl_map_t tl_map; |
46 | |
59 | |
47 | /* |
60 | /* |
48 | * Initialize global archtype pointers: |
61 | * Initialize global archtype pointers: |
49 | */ |
62 | */ |
50 | |
|
|
51 | void |
63 | void |
52 | init_archetype_pointers () |
64 | init_archetype_pointers () |
53 | { |
65 | { |
54 | int prev_warn = warn_archetypes; |
66 | int prev_warn = warn_archetypes; |
55 | |
67 | |
56 | warn_archetypes = 1; |
68 | warn_archetypes = 1; |
|
|
69 | |
57 | if (ring_arch == NULL) |
70 | if (ring_arch == NULL) |
58 | ring_arch = archetype::find ("ring"); |
71 | ring_arch = archetype::find ("ring"); |
59 | if (amulet_arch == NULL) |
72 | if (amulet_arch == NULL) |
60 | amulet_arch = archetype::find ("amulet"); |
73 | amulet_arch = archetype::find ("amulet"); |
61 | if (staff_arch == NULL) |
74 | if (staff_arch == NULL) |
62 | staff_arch = archetype::find ("staff"); |
75 | staff_arch = archetype::find ("staff"); |
63 | if (crown_arch == NULL) |
76 | if (crown_arch == NULL) |
64 | crown_arch = archetype::find ("crown"); |
77 | crown_arch = archetype::find ("crown"); |
|
|
78 | |
65 | warn_archetypes = prev_warn; |
79 | warn_archetypes = prev_warn; |
66 | } |
80 | } |
67 | |
81 | |
68 | /* |
82 | /* |
69 | * Allocate and return the pointer to an empty treasurelist structure. |
83 | * Searches for the given treasurelist in the globally linked list |
|
|
84 | * of treasurelists which has been built by load_treasures(). |
70 | */ |
85 | */ |
71 | |
|
|
72 | static treasurelist * |
86 | treasurelist * |
73 | get_empty_treasurelist (void) |
87 | treasurelist::find (const char *name) |
74 | { |
88 | { |
|
|
89 | if (!name) |
|
|
90 | return 0; |
|
|
91 | |
|
|
92 | AUTODECL (i, tl_map.find (name)); |
|
|
93 | |
|
|
94 | if (i == tl_map.end ()) |
|
|
95 | return 0; |
|
|
96 | |
|
|
97 | return i->second; |
|
|
98 | } |
|
|
99 | |
|
|
100 | /* |
|
|
101 | * Searches for the given treasurelist in the globally linked list |
|
|
102 | * of treasurelists which has been built by load_treasures(). |
|
|
103 | */ |
|
|
104 | treasurelist * |
|
|
105 | treasurelist::get (const char *name) |
|
|
106 | { |
|
|
107 | treasurelist *tl = find (name); |
|
|
108 | |
|
|
109 | if (!tl) |
|
|
110 | { |
75 | return new treasurelist; |
111 | tl = new treasurelist; |
76 | } |
|
|
77 | |
112 | |
78 | /* |
113 | tl->name = name; |
79 | * Allocate and return the pointer to an empty treasure structure. |
114 | tl->next = first_treasurelist; |
80 | */ |
115 | first_treasurelist = tl; |
81 | //TODO: make this a constructor |
|
|
82 | static treasure * |
|
|
83 | get_empty_treasure (void) |
|
|
84 | { |
|
|
85 | treasure *t = new treasure; |
|
|
86 | |
116 | |
87 | t->chance = 100; |
117 | tl_map.insert (std::make_pair (tl->name, tl)); |
|
|
118 | } |
88 | |
119 | |
89 | return t; |
120 | return tl; |
|
|
121 | } |
|
|
122 | |
|
|
123 | //TODO: class method |
|
|
124 | void |
|
|
125 | clear (treasurelist *tl) |
|
|
126 | { |
|
|
127 | if (tl->items) |
|
|
128 | { |
|
|
129 | free_treasurestruct (tl->items); |
|
|
130 | tl->items = 0; |
|
|
131 | } |
90 | } |
132 | } |
91 | |
133 | |
92 | /* |
134 | /* |
93 | * Reads the lib/treasure file from disk, and parses the contents |
135 | * Reads the lib/treasure file from disk, and parses the contents |
94 | * into an internal treasure structure (very linked lists) |
136 | * into an internal treasure structure (very linked lists) |
… | |
… | |
96 | |
138 | |
97 | static treasure * |
139 | static treasure * |
98 | load_treasure (FILE * fp, int *line) |
140 | load_treasure (FILE * fp, int *line) |
99 | { |
141 | { |
100 | char buf[MAX_BUF], *cp, variable[MAX_BUF]; |
142 | char buf[MAX_BUF], *cp, variable[MAX_BUF]; |
101 | treasure *t = get_empty_treasure (); |
143 | treasure *t = new treasure; |
102 | int value; |
144 | int value; |
103 | |
145 | |
104 | nroftreasures++; |
146 | nroftreasures++; |
105 | while (fgets (buf, MAX_BUF, fp) != NULL) |
147 | while (fgets (buf, MAX_BUF, fp) != NULL) |
106 | { |
148 | { |
… | |
… | |
159 | static void |
201 | static void |
160 | check_treasurelist (const treasure *t, const treasurelist * tl) |
202 | check_treasurelist (const treasure *t, const treasurelist * tl) |
161 | { |
203 | { |
162 | if (t->chance >= 100 && t->next_yes && (t->next || t->next_no)) |
204 | 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); |
205 | 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 */ |
206 | |
165 | if (t->name && *t->name) |
|
|
166 | find_treasurelist (t->name); |
|
|
167 | if (t->next) |
207 | if (t->next) |
168 | check_treasurelist (t->next, tl); |
208 | check_treasurelist (t->next, tl); |
|
|
209 | |
169 | if (t->next_yes) |
210 | if (t->next_yes) |
170 | check_treasurelist (t->next_yes, tl); |
211 | check_treasurelist (t->next_yes, tl); |
|
|
212 | |
171 | if (t->next_no) |
213 | if (t->next_no) |
172 | check_treasurelist (t->next_no, tl); |
214 | check_treasurelist (t->next_no, tl); |
173 | } |
215 | } |
174 | #endif |
216 | #endif |
175 | |
217 | |
… | |
… | |
181 | void |
223 | void |
182 | load_treasures (void) |
224 | load_treasures (void) |
183 | { |
225 | { |
184 | FILE *fp; |
226 | FILE *fp; |
185 | char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF]; |
227 | char filename[MAX_BUF], buf[MAX_BUF], name[MAX_BUF]; |
186 | treasurelist *previous = NULL; |
|
|
187 | treasure *t; |
228 | treasure *t; |
188 | int comp, line = 0; |
229 | int comp, line = 0; |
189 | |
230 | |
190 | sprintf (filename, "%s/%s", settings.datadir, settings.treasures); |
231 | sprintf (filename, "%s/%s", settings.datadir, settings.treasures); |
191 | if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL) |
232 | if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL) |
… | |
… | |
198 | line++; |
239 | line++; |
199 | if (*buf == '#' || *buf == '\n') |
240 | if (*buf == '#' || *buf == '\n') |
200 | ; // ignore |
241 | ; // ignore |
201 | else if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name)) |
242 | else if (sscanf (buf, "treasureone %s\n", name) || sscanf (buf, "treasure %s\n", name)) |
202 | { |
243 | { |
203 | treasurelist *tl = get_empty_treasurelist (); |
244 | treasurelist *tl = treasurelist::get (name); |
204 | |
245 | |
205 | tl->name = name; |
246 | clear (tl); |
206 | if (previous == NULL) |
|
|
207 | first_treasurelist = tl; |
|
|
208 | else |
|
|
209 | previous->next = tl; |
|
|
210 | |
|
|
211 | previous = tl; |
|
|
212 | tl->items = load_treasure (fp, &line); |
247 | tl->items = load_treasure (fp, &line); |
213 | |
248 | |
214 | /* This is a one of the many items on the list should be generated. |
249 | /* 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 |
250 | * Add up the chance total, and check to make sure the yes & no |
216 | * fields of the treasures are not being used. |
251 | * fields of the treasures are not being used. |
217 | */ |
252 | */ |
218 | if (!strncmp (buf, "treasureone", 11)) |
253 | if (!strncmp (buf, "treasureone", 11)) |
219 | { |
254 | { |
220 | for (t = tl->items; t != NULL; t = t->next) |
255 | for (t = tl->items; t; t = t->next) |
221 | { |
256 | { |
222 | #ifdef TREASURE_DEBUG |
257 | #ifdef TREASURE_DEBUG |
223 | if (t->next_yes || t->next_no) |
258 | if (t->next_yes || t->next_no) |
224 | { |
259 | { |
225 | LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); |
260 | LOG (llevError, "Treasure %s is one item, but on treasure %s\n", &tl->name, t->item ? &t->item->name : &t->name); |
… | |
… | |
231 | } |
266 | } |
232 | } |
267 | } |
233 | else |
268 | else |
234 | LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line); |
269 | LOG (llevError, "Treasure-list %s didn't understand: %s, line %d\n", filename, buf, line); |
235 | } |
270 | } |
|
|
271 | |
236 | close_and_delete (fp, comp); |
272 | close_and_delete (fp, comp); |
237 | |
273 | |
238 | #ifdef TREASURE_DEBUG |
274 | #ifdef TREASURE_DEBUG |
239 | /* Perform some checks on how valid the treasure data actually is. |
275 | /* Perform some checks on how valid the treasure data actually is. |
240 | * verify that list transitions work (ie, the list that it is supposed |
276 | * verify that list transitions work (ie, the list that it is supposed |
241 | * to transition to exists). Also, verify that at least the name |
277 | * to transition to exists). Also, verify that at least the name |
242 | * or archetype is set for each treasure element. |
278 | * or archetype is set for each treasure element. |
243 | */ |
279 | */ |
244 | for (previous = first_treasurelist; previous != NULL; previous = previous->next) |
280 | for (treasurelist *tl = first_treasurelist; tl; tl = tl->next) |
245 | check_treasurelist (previous->items, previous); |
281 | check_treasurelist (tl->items, tl); |
246 | #endif |
282 | #endif |
247 | } |
283 | } |
248 | |
|
|
249 | /* |
|
|
250 | * Searches for the given treasurelist in the globally linked list |
|
|
251 | * of treasurelists which has been built by load_treasures(). |
|
|
252 | */ |
|
|
253 | |
|
|
254 | treasurelist * |
|
|
255 | find_treasurelist (const char *name) |
|
|
256 | { |
|
|
257 | shstr_cmp name_ (name); |
|
|
258 | |
|
|
259 | if (!name_) |
|
|
260 | return 0; |
|
|
261 | |
|
|
262 | for (treasurelist *tl = first_treasurelist; tl != 0; tl = tl->next) |
|
|
263 | if (name_ == tl->name) |
|
|
264 | return tl; |
|
|
265 | |
|
|
266 | if (first_treasurelist) |
|
|
267 | LOG (llevError, "Couldn't find treasurelist %s\n", name); |
|
|
268 | |
|
|
269 | return 0; |
|
|
270 | } |
|
|
271 | |
|
|
272 | |
284 | |
273 | /* |
285 | /* |
274 | * Generates the objects specified by the given treasure. |
286 | * Generates the objects specified by the given treasure. |
275 | * It goes recursively through the rest of the linked list. |
287 | * It goes recursively through the rest of the linked list. |
276 | * If there is a certain percental chance for a treasure to be generated, |
288 | * If there is a certain percental chance for a treasure to be generated, |
… | |
… | |
326 | |
338 | |
327 | if (t->change_arch.slaying) |
339 | if (t->change_arch.slaying) |
328 | op->slaying = t->change_arch.slaying; |
340 | op->slaying = t->change_arch.slaying; |
329 | } |
341 | } |
330 | |
342 | |
331 | void |
343 | static void |
332 | create_all_treasures (treasure *t, object *op, int flag, int difficulty, int tries) |
344 | create_all_treasures (treasure *t, object *op, int flag, int difficulty, int tries) |
333 | { |
345 | { |
334 | object *tmp; |
|
|
335 | |
|
|
336 | if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance) |
346 | if ((int) t->chance >= 100 || (rndm (100) + 1) < (int) t->chance) |
337 | { |
347 | { |
338 | if (t->name) |
348 | if (t->name) |
339 | { |
349 | { |
340 | if (difficulty >= t->magic) |
350 | if (difficulty >= t->magic) |
341 | { |
|
|
342 | treasurelist *tl = find_treasurelist (t->name); |
|
|
343 | if (tl) |
|
|
344 | create_treasure (tl, op, flag, difficulty, tries); |
351 | create_treasure (treasurelist::find (t->name), op, flag, difficulty, tries); |
345 | } |
|
|
346 | } |
352 | } |
347 | else |
353 | else |
348 | { |
354 | { |
349 | if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE))) |
355 | if (t->item && (t->item->clone.invisible != 0 || !(flag & GT_INVISIBLE))) |
350 | { |
356 | { |
351 | tmp = arch_to_object (t->item); |
357 | object *tmp = arch_to_object (t->item); |
|
|
358 | |
352 | if (t->nrof && tmp->nrof <= 1) |
359 | if (t->nrof && tmp->nrof <= 1) |
353 | tmp->nrof = rndm (t->nrof) + 1; |
360 | tmp->nrof = rndm (t->nrof) + 1; |
354 | |
361 | |
355 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
362 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
356 | change_treasure (t, tmp); |
363 | change_treasure (t, tmp); |
357 | put_treasure (tmp, op, flag); |
364 | put_treasure (tmp, op, flag); |
358 | } |
365 | } |
359 | } |
366 | } |
360 | |
367 | |
361 | if (t->next_yes != NULL) |
368 | if (t->next_yes) |
362 | create_all_treasures (t->next_yes, op, flag, difficulty, tries); |
369 | create_all_treasures (t->next_yes, op, flag, difficulty, tries); |
363 | } |
370 | } |
364 | else if (t->next_no != NULL) |
371 | else if (t->next_no) |
365 | create_all_treasures (t->next_no, op, flag, difficulty, tries); |
372 | create_all_treasures (t->next_no, op, flag, difficulty, tries); |
366 | |
373 | |
367 | if (t->next != NULL) |
374 | if (t->next) |
368 | create_all_treasures (t->next, op, flag, difficulty, tries); |
375 | create_all_treasures (t->next, op, flag, difficulty, tries); |
369 | } |
376 | } |
370 | |
377 | |
371 | void |
378 | static void |
372 | create_one_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries) |
379 | create_one_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries) |
373 | { |
380 | { |
374 | int value = rndm (tl->total_chance); |
381 | int value = rndm (tl->total_chance); |
375 | treasure *t; |
382 | treasure *t; |
376 | |
383 | |
… | |
… | |
378 | { |
385 | { |
379 | LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n"); |
386 | LOG (llevDebug, "create_one_treasure: tries exceeded 100, returning without making treasure\n"); |
380 | return; |
387 | return; |
381 | } |
388 | } |
382 | |
389 | |
383 | for (t = tl->items; t != NULL; t = t->next) |
390 | for (t = tl->items; t; t = t->next) |
384 | { |
391 | { |
385 | value -= t->chance; |
392 | value -= t->chance; |
386 | |
393 | |
387 | if (value < 0) |
394 | if (value < 0) |
388 | break; |
395 | break; |
389 | } |
396 | } |
390 | |
397 | |
391 | if (!t || value >= 0) |
398 | if (!t || value >= 0) |
392 | { |
|
|
393 | LOG (llevError, "create_one_treasure: got null object or not able to find treasure\n"); |
399 | cleanup ("create_one_treasure: got null object or not able to find treasure\n", 1); |
394 | abort (); |
|
|
395 | return; |
|
|
396 | } |
|
|
397 | |
400 | |
398 | if (t->name) |
401 | if (t->name) |
399 | { |
402 | { |
400 | if (difficulty >= t->magic) |
403 | if (difficulty >= t->magic) |
401 | { |
404 | { |
402 | treasurelist *tl = find_treasurelist (t->name); |
405 | treasurelist *tl = treasurelist::find (t->name); |
403 | if (tl) |
406 | if (tl) |
404 | create_treasure (tl, op, flag, difficulty, tries); |
407 | create_treasure (tl, op, flag, difficulty, tries); |
405 | } |
408 | } |
406 | else if (t->nrof) |
409 | else if (t->nrof) |
407 | create_one_treasure (tl, op, flag, difficulty, tries); |
410 | create_one_treasure (tl, op, flag, difficulty, tries); |
408 | |
|
|
409 | return; |
|
|
410 | } |
411 | } |
411 | |
|
|
412 | if (t->item && (t->item->clone.invisible != 0 || flag != GT_INVISIBLE)) |
412 | else if (t->item && (t->item->clone.invisible != 0 || flag != GT_INVISIBLE)) |
413 | { |
413 | { |
414 | object *tmp = arch_to_object (t->item); |
414 | if (object *tmp = arch_to_object (t->item)) |
415 | |
415 | { |
416 | if (!tmp) |
|
|
417 | return; |
|
|
418 | |
|
|
419 | if (t->nrof && tmp->nrof <= 1) |
416 | if (t->nrof && tmp->nrof <= 1) |
420 | tmp->nrof = rndm (t->nrof) + 1; |
417 | tmp->nrof = rndm (t->nrof) + 1; |
421 | |
418 | |
422 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
419 | fix_generated_item (tmp, op, difficulty, t->magic, flag); |
423 | change_treasure (t, tmp); |
420 | change_treasure (t, tmp); |
424 | put_treasure (tmp, op, flag); |
421 | put_treasure (tmp, op, flag); |
|
|
422 | } |
425 | } |
423 | } |
426 | } |
424 | } |
427 | |
425 | |
428 | /* This calls the appropriate treasure creation function. tries is passed |
426 | /* This calls the appropriate treasure creation function. tries is passed |
429 | * to determine how many list transitions or attempts to create treasure |
427 | * to determine how many list transitions or attempts to create treasure |
… | |
… | |
433 | * to do that. |
431 | * to do that. |
434 | */ |
432 | */ |
435 | void |
433 | void |
436 | create_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries) |
434 | create_treasure (treasurelist *tl, object *op, int flag, int difficulty, int tries) |
437 | { |
435 | { |
|
|
436 | // empty treasurelists are legal |
|
|
437 | if (!tl->items) |
|
|
438 | return; |
|
|
439 | |
438 | if (tries++ > 100) |
440 | if (tries++ > 100) |
439 | { |
441 | { |
440 | LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n"); |
442 | LOG (llevDebug, "createtreasure: tries exceeded 100, returning without making treasure\n"); |
441 | return; |
443 | return; |
442 | } |
444 | } |
… | |
… | |
556 | * elmex Thu Aug 10 18:45:44 CEST 2006: |
558 | * elmex Thu Aug 10 18:45:44 CEST 2006: |
557 | * Scaling difficulty by max_level, as difficulty is a level and not some |
559 | * Scaling difficulty by max_level, as difficulty is a level and not some |
558 | * weird integer between 1-31. |
560 | * weird integer between 1-31. |
559 | * |
561 | * |
560 | */ |
562 | */ |
561 | |
|
|
562 | int |
563 | int |
563 | magic_from_difficulty (int difficulty) |
564 | magic_from_difficulty (int difficulty) |
564 | { |
565 | { |
565 | int percent = 0, magic = 0; |
566 | int percent = 0, magic = 0; |
566 | int scaled_diff = (int) (((double) difficulty / settings.max_level) * DIFFLEVELS); |
567 | int scaled_diff = (int) (((double) difficulty / settings.max_level) * DIFFLEVELS); |
… | |
… | |
654 | * 1) Since rings can have multiple bonuses, if the same bonus |
655 | * 1) Since rings can have multiple bonuses, if the same bonus |
655 | * is rolled again, increase it - the bonuses now stack with |
656 | * is rolled again, increase it - the bonuses now stack with |
656 | * other bonuses previously rolled and ones the item might natively have. |
657 | * other bonuses previously rolled and ones the item might natively have. |
657 | * 2) Add code to deal with new PR method. |
658 | * 2) Add code to deal with new PR method. |
658 | */ |
659 | */ |
659 | |
|
|
660 | void |
660 | void |
661 | set_ring_bonus (object *op, int bonus) |
661 | set_ring_bonus (object *op, int bonus) |
662 | { |
662 | { |
663 | |
663 | |
664 | int r = rndm (bonus > 0 ? 25 : 11); |
664 | int r = rndm (bonus > 0 ? 25 : 11); |
… | |
… | |
1176 | * Allocate and return the pointer to an empty artifactlist structure. |
1176 | * Allocate and return the pointer to an empty artifactlist structure. |
1177 | */ |
1177 | */ |
1178 | static artifactlist * |
1178 | static artifactlist * |
1179 | get_empty_artifactlist (void) |
1179 | get_empty_artifactlist (void) |
1180 | { |
1180 | { |
1181 | artifactlist *al = (artifactlist *) malloc (sizeof (artifactlist)); |
1181 | return salloc0 <artifactlist> (); |
1182 | |
|
|
1183 | if (al == NULL) |
|
|
1184 | fatal (OUT_OF_MEMORY); |
|
|
1185 | al->next = NULL; |
|
|
1186 | al->items = NULL; |
|
|
1187 | al->total_chance = 0; |
|
|
1188 | return al; |
|
|
1189 | } |
1182 | } |
1190 | |
1183 | |
1191 | /* |
1184 | /* |
1192 | * Allocate and return the pointer to an empty artifact structure. |
1185 | * Allocate and return the pointer to an empty artifact structure. |
1193 | */ |
1186 | */ |
1194 | static artifact * |
1187 | static artifact * |
1195 | get_empty_artifact (void) |
1188 | get_empty_artifact (void) |
1196 | { |
1189 | { |
1197 | artifact *a = (artifact *) malloc (sizeof (artifact)); |
1190 | return salloc0 <artifact> (); |
1198 | |
|
|
1199 | if (a == NULL) |
|
|
1200 | fatal (OUT_OF_MEMORY); |
|
|
1201 | |
|
|
1202 | a->item = NULL; |
|
|
1203 | a->next = NULL; |
|
|
1204 | a->chance = 0; |
|
|
1205 | a->difficulty = 0; |
|
|
1206 | a->allowed = NULL; |
|
|
1207 | return a; |
|
|
1208 | } |
1191 | } |
1209 | |
1192 | |
1210 | /* |
1193 | /* |
1211 | * Searches the artifact lists and returns one that has the same type |
1194 | * Searches the artifact lists and returns one that has the same type |
1212 | * of objects on it. |
1195 | * of objects on it. |
1213 | */ |
1196 | */ |
1214 | artifactlist * |
1197 | artifactlist * |
1215 | find_artifactlist (int type) |
1198 | find_artifactlist (int type) |
1216 | { |
1199 | { |
1217 | artifactlist *al; |
|
|
1218 | |
|
|
1219 | for (al = first_artifactlist; al; al = al->next) |
1200 | for (artifactlist *al = first_artifactlist; al; al = al->next) |
1220 | if (al->type == type) |
1201 | if (al->type == type) |
1221 | return al; |
1202 | return al; |
1222 | |
1203 | |
1223 | return 0; |
1204 | return 0; |
1224 | } |
1205 | } |
… | |
… | |
1261 | treasurelist *tl; |
1242 | treasurelist *tl; |
1262 | int i; |
1243 | int i; |
1263 | |
1244 | |
1264 | if (depth > 100) |
1245 | if (depth > 100) |
1265 | return; |
1246 | return; |
|
|
1247 | |
1266 | while (t) |
1248 | while (t) |
1267 | { |
1249 | { |
1268 | if (t->name) |
1250 | if (t->name) |
1269 | { |
1251 | { |
1270 | for (i = 0; i < depth; i++) |
1252 | for (i = 0; i < depth; i++) |
1271 | fprintf (logfile, " "); |
1253 | fprintf (logfile, " "); |
|
|
1254 | |
1272 | fprintf (logfile, "{ (list: %s)\n", &t->name); |
1255 | fprintf (logfile, "{ (list: %s)\n", &t->name); |
|
|
1256 | |
1273 | tl = find_treasurelist (t->name); |
1257 | tl = treasurelist::find (t->name); |
1274 | if (tl) |
1258 | if (tl) |
1275 | dump_monster_treasure_rec (name, tl->items, depth + 2); |
1259 | dump_monster_treasure_rec (name, tl->items, depth + 2); |
|
|
1260 | |
1276 | for (i = 0; i < depth; i++) |
1261 | for (i = 0; i < depth; i++) |
1277 | fprintf (logfile, " "); |
1262 | fprintf (logfile, " "); |
|
|
1263 | |
1278 | fprintf (logfile, "} (end of list: %s)\n", &t->name); |
1264 | fprintf (logfile, "} (end of list: %s)\n", &t->name); |
1279 | } |
1265 | } |
1280 | else |
1266 | else |
1281 | { |
1267 | { |
1282 | for (i = 0; i < depth; i++) |
1268 | for (i = 0; i < depth; i++) |
1283 | fprintf (logfile, " "); |
1269 | fprintf (logfile, " "); |
|
|
1270 | |
1284 | if (t->item && t->item->clone.type == FLESH) |
1271 | if (t->item && t->item->clone.type == FLESH) |
1285 | fprintf (logfile, "%s's %s\n", name, &t->item->clone.name); |
1272 | fprintf (logfile, "%s's %s\n", name, &t->item->clone.name); |
1286 | else |
1273 | else |
1287 | fprintf (logfile, "%s\n", &t->item->clone.name); |
1274 | fprintf (logfile, "%s\n", &t->item->clone.name); |
1288 | } |
1275 | } |
1289 | |
1276 | |
1290 | if (t->next_yes) |
1277 | if (t->next_yes) |
1291 | { |
1278 | { |
1292 | for (i = 0; i < depth; i++) |
1279 | for (i = 0; i < depth; i++) |
1293 | fprintf (logfile, " "); |
1280 | fprintf (logfile, " "); |
|
|
1281 | |
1294 | fprintf (logfile, " (if yes)\n"); |
1282 | fprintf (logfile, " (if yes)\n"); |
1295 | dump_monster_treasure_rec (name, t->next_yes, depth + 1); |
1283 | dump_monster_treasure_rec (name, t->next_yes, depth + 1); |
1296 | } |
1284 | } |
1297 | |
1285 | |
1298 | if (t->next_no) |
1286 | if (t->next_no) |
1299 | { |
1287 | { |
1300 | for (i = 0; i < depth; i++) |
1288 | for (i = 0; i < depth; i++) |
1301 | fprintf (logfile, " "); |
1289 | fprintf (logfile, " "); |
|
|
1290 | |
1302 | fprintf (logfile, " (if no)\n"); |
1291 | fprintf (logfile, " (if no)\n"); |
1303 | dump_monster_treasure_rec (name, t->next_no, depth + 1); |
1292 | dump_monster_treasure_rec (name, t->next_no, depth + 1); |
1304 | } |
1293 | } |
1305 | |
1294 | |
1306 | t = t->next; |
1295 | t = t->next; |
… | |
… | |
1309 | |
1298 | |
1310 | /* |
1299 | /* |
1311 | * For debugging purposes. Dumps all treasures for a given monster. |
1300 | * For debugging purposes. Dumps all treasures for a given monster. |
1312 | * Created originally by Raphael Quinet for debugging the alchemy code. |
1301 | * Created originally by Raphael Quinet for debugging the alchemy code. |
1313 | */ |
1302 | */ |
1314 | |
|
|
1315 | void |
1303 | void |
1316 | dump_monster_treasure (const char *name) |
1304 | dump_monster_treasure (const char *name) |
1317 | { |
1305 | { |
1318 | archetype *at; |
1306 | archetype *at; |
1319 | int found; |
1307 | int found; |
… | |
… | |
1842 | } |
1830 | } |
1843 | |
1831 | |
1844 | void |
1832 | void |
1845 | free_treasurestruct (treasure *t) |
1833 | free_treasurestruct (treasure *t) |
1846 | { |
1834 | { |
1847 | if (t->next) |
|
|
1848 | free_treasurestruct (t->next); |
1835 | if (t->next) free_treasurestruct (t->next); |
1849 | if (t->next_yes) |
|
|
1850 | free_treasurestruct (t->next_yes); |
1836 | if (t->next_yes) free_treasurestruct (t->next_yes); |
1851 | if (t->next_no) |
|
|
1852 | free_treasurestruct (t->next_no); |
1837 | if (t->next_no) free_treasurestruct (t->next_no); |
1853 | |
1838 | |
1854 | delete t; |
1839 | delete t; |
1855 | } |
1840 | } |
1856 | |
1841 | |
1857 | void |
1842 | void |
… | |
… | |
1862 | |
1847 | |
1863 | delete lc; |
1848 | delete lc; |
1864 | } |
1849 | } |
1865 | |
1850 | |
1866 | void |
1851 | void |
1867 | free_artifact (artifact * at) |
1852 | free_artifact (artifact *at) |
1868 | { |
1853 | { |
1869 | if (at->next) |
|
|
1870 | free_artifact (at->next); |
1854 | if (at->next) free_artifact (at->next); |
1871 | |
|
|
1872 | if (at->allowed) |
|
|
1873 | free_charlinks (at->allowed); |
1855 | if (at->allowed) free_charlinks (at->allowed); |
1874 | |
1856 | |
1875 | at->item->destroy (1); |
1857 | at->item->destroy (1); |
1876 | |
1858 | |
1877 | delete at; |
1859 | sfree (at); |
1878 | } |
1860 | } |
1879 | |
1861 | |
1880 | void |
1862 | void |
1881 | free_artifactlist (artifactlist * al) |
1863 | free_artifactlist (artifactlist *al) |
1882 | { |
1864 | { |
1883 | artifactlist *nextal; |
1865 | artifactlist *nextal; |
1884 | |
1866 | |
1885 | for (al = first_artifactlist; al; al = nextal) |
1867 | for (al = first_artifactlist; al; al = nextal) |
1886 | { |
1868 | { |
1887 | nextal = al->next; |
1869 | nextal = al->next; |
1888 | |
1870 | |
1889 | if (al->items) |
1871 | if (al->items) |
1890 | free_artifact (al->items); |
1872 | free_artifact (al->items); |
1891 | |
1873 | |
1892 | free (al); |
1874 | sfree (al); |
1893 | } |
1875 | } |
1894 | } |
1876 | } |
1895 | |
1877 | |
1896 | void |
1878 | void |
1897 | free_all_treasures (void) |
1879 | free_all_treasures (void) |
1898 | { |
1880 | { |
1899 | treasurelist *tl, *next; |
1881 | treasurelist *tl, *next; |
1900 | |
1882 | |
1901 | |
|
|
1902 | for (tl = first_treasurelist; tl != NULL; tl = next) |
1883 | for (tl = first_treasurelist; tl; tl = next) |
1903 | { |
1884 | { |
|
|
1885 | clear (tl); |
|
|
1886 | |
1904 | next = tl->next; |
1887 | next = tl->next; |
1905 | if (tl->items) |
|
|
1906 | free_treasurestruct (tl->items); |
|
|
1907 | delete tl; |
1888 | delete tl; |
1908 | } |
1889 | } |
|
|
1890 | |
1909 | free_artifactlist (first_artifactlist); |
1891 | free_artifactlist (first_artifactlist); |
1910 | } |
1892 | } |