… | |
… | |
321 | } |
321 | } |
322 | |
322 | |
323 | return 0; |
323 | return 0; |
324 | } |
324 | } |
325 | |
325 | |
326 | /* If several archetypes have the same name, the value of the first |
|
|
327 | * one with that name will be returned. This happens for the |
|
|
328 | * mushrooms (mushroom_1, mushroom_2 and mushroom_3). For the |
|
|
329 | * monsters' body parts, there may be several monsters with the same |
|
|
330 | * name. This is not a problem if these monsters have the same level |
|
|
331 | * (e.g. sage & c_sage) or if only one of the monsters generates the |
|
|
332 | * body parts that we are looking for (e.g. big_dragon and |
|
|
333 | * big_dragon_worthless). */ |
|
|
334 | static long |
|
|
335 | find_ingred_cost (const char *name) |
|
|
336 | { |
|
|
337 | archetype *at2; |
|
|
338 | artifactlist *al; |
|
|
339 | artifact *art; |
|
|
340 | long mult; |
|
|
341 | char *cp; |
|
|
342 | char part1[100]; |
|
|
343 | char part2[100]; |
|
|
344 | |
|
|
345 | /* same as atoi(), but skip number */ |
|
|
346 | mult = 0; |
|
|
347 | while (isdigit (*name)) |
|
|
348 | { |
|
|
349 | mult = 10 * mult + (*name - '0'); |
|
|
350 | name++; |
|
|
351 | } |
|
|
352 | |
|
|
353 | if (mult > 0) |
|
|
354 | name++; |
|
|
355 | else |
|
|
356 | mult = 1; |
|
|
357 | |
|
|
358 | /* first, try to match the name of an archetype */ |
|
|
359 | for_all_archetypes (at) |
|
|
360 | { |
|
|
361 | if (at->title != NULL) |
|
|
362 | { |
|
|
363 | /* inefficient, but who cares? */ |
|
|
364 | sprintf (part1, "%s %s", &at->object::name, &at->title); |
|
|
365 | if (!strcasecmp (part1, name)) |
|
|
366 | return mult * at->value; |
|
|
367 | } |
|
|
368 | if (!strcasecmp (at->object::name, name)) |
|
|
369 | return mult * at->value; |
|
|
370 | } |
|
|
371 | |
|
|
372 | /* second, try to match an artifact ("arch of something") */ |
|
|
373 | cp = strstr (name, " of "); |
|
|
374 | if (cp != NULL) |
|
|
375 | { |
|
|
376 | strcpy (part1, name); |
|
|
377 | part1[cp - name] = '\0'; |
|
|
378 | strcpy (part2, cp + 4); |
|
|
379 | |
|
|
380 | /* find the first archetype matching the first part of the name */ |
|
|
381 | for_all_archetypes (at) |
|
|
382 | if (at->object::name.eq_nc (part1) && !at->title) |
|
|
383 | { |
|
|
384 | /* find the first artifact derived from that archetype (same type) */ |
|
|
385 | for (al = first_artifactlist; al; al = al->next) |
|
|
386 | if (al->type == at->type) |
|
|
387 | { |
|
|
388 | for (art = al->items; art; art = art->next) |
|
|
389 | if (!strcasecmp (art->item->name, part2)) |
|
|
390 | return mult * at->value * art->item->value; |
|
|
391 | } |
|
|
392 | } |
|
|
393 | } |
|
|
394 | |
|
|
395 | /* third, try to match a body part ("arch's something") */ |
|
|
396 | cp = strstr (name, "'s "); |
|
|
397 | if (cp) |
|
|
398 | { |
|
|
399 | strcpy (part1, name); |
|
|
400 | part1[cp - name] = '\0'; |
|
|
401 | strcpy (part2, cp + 3); |
|
|
402 | /* examine all archetypes matching the first part of the name */ |
|
|
403 | for_all_archetypes (at) |
|
|
404 | if (at->object::name.eq_nc (part1) && !at->title) |
|
|
405 | { |
|
|
406 | if (at->randomitems) |
|
|
407 | { |
|
|
408 | at2 = find_treasure_by_name (at->randomitems->items, part2, 0); |
|
|
409 | if (at2) |
|
|
410 | return mult * at2->value * isqrt (at->level * 2); |
|
|
411 | } |
|
|
412 | } |
|
|
413 | } |
|
|
414 | |
|
|
415 | /* failed to find any matching items -- formula should be checked */ |
|
|
416 | return -1; |
|
|
417 | } |
|
|
418 | |
|
|
419 | static const char * |
326 | static const char * |
420 | ingred_name (const char *name) |
327 | ingred_name (const char *name) |
421 | { |
328 | { |
422 | const char *cp = name; |
329 | const char *cp = name; |
423 | |
330 | |
… | |
… | |
525 | if (r < 0) |
432 | if (r < 0) |
526 | break; |
433 | break; |
527 | } |
434 | } |
528 | } |
435 | } |
529 | return rp; |
436 | return rp; |
530 | } |
|
|
531 | |
|
|
532 | static void |
|
|
533 | free_all_recipes (void) |
|
|
534 | { |
|
|
535 | recipelist *fl = formulalist, *flnext; |
|
|
536 | recipe *formula = NULL, *next; |
|
|
537 | linked_char *lchar, *charnext; |
|
|
538 | |
|
|
539 | LOG (llevDebug, "Freeing all the recipes\n"); |
|
|
540 | for (fl = formulalist; fl != NULL; fl = flnext) |
|
|
541 | { |
|
|
542 | flnext = fl->next; |
|
|
543 | |
|
|
544 | for (formula = fl->items; formula != NULL; formula = next) |
|
|
545 | { |
|
|
546 | next = formula->next; |
|
|
547 | |
|
|
548 | free (formula->arch_name[0]); |
|
|
549 | free (formula->arch_name); |
|
|
550 | |
|
|
551 | for (lchar = formula->ingred; lchar; lchar = charnext) |
|
|
552 | { |
|
|
553 | charnext = lchar->next; |
|
|
554 | delete lchar; |
|
|
555 | } |
|
|
556 | delete formula; |
|
|
557 | } |
|
|
558 | |
|
|
559 | delete fl; |
|
|
560 | } |
|
|
561 | } |
437 | } |
562 | |
438 | |
563 | /** |
439 | /** |
564 | * Split a comma separated string list into words. |
440 | * Split a comma separated string list into words. |
565 | * |
441 | * |