Crossfire Server, Trunk
recipe.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
35 #include "global.h"
36 
37 #include <assert.h>
38 #include <ctype.h>
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #include "object.h"
43 #include "assets.h"
44 #include "AssetsManager.h"
45 
46 static void build_stringlist(const char *str, char ***result_list, size_t *result_size);
47 
50 
59 static recipelist *init_recipelist(void) {
60  recipelist *tl = (recipelist *)malloc(sizeof(recipelist));
61  if (tl == NULL)
63  tl->total_chance = 0;
64  tl->number = 0;
65  tl->items = NULL;
66  tl->next = NULL;
67  return tl;
68 }
69 
78 static recipe *get_empty_formula(void) {
79  // This used to be a malloc followed by setting everything to zero.
80  // So just use calloc to make it faster.
81  // SilverNexus -- 2018-10-22
82  recipe *t = (recipe *)calloc(1, sizeof(recipe));
83  if (t == NULL)
85  return t;
86 }
87 
98  recipelist *fl = formulalist;
99  int number = i;
100 
101  while (fl && number > 1) {
102  if (!(fl = fl->next))
103  break;
104  number--;
105  }
106  return fl;
107 }
108 
119 static int check_recipe(const recipe *rp) {
120  size_t i;
121  int result;
122 
123  result = 1;
124  for (i = 0; i < rp->arch_names; i++) {
125  if (try_find_archetype(rp->arch_name[i]) != NULL) {
126  if (strcmp(rp->title, "NONE")) {
127  const artifact *art = locate_recipe_artifact(rp, i);
128 
129  if (!art) {
130  LOG(llevError, "Formula %s of %s has no artifact.\n", rp->arch_name[i], rp->title);
131  result = 0;
132  }
133  }
134  } else {
135  LOG(llevError, "Can't find archetype %s for formula %s\n", rp->arch_name[i], rp->title);
136  result = 0;
137  }
138  }
139 
140  return result;
141 }
142 
148  const recipelist *rl = formulalist;
149  int abort = 0;
150  while (rl) {
151  const recipe *rp = rl->items;
152  while (rp) {
153  if (!check_recipe(rp)) {
154  abort = 1;
155  }
156  rp = rp->next;
157  }
158  rl = rl->next;
159  }
160  if (abort) {
162  }
163 }
164 
168 void init_formulae(BufferReader *reader, const char *filename) {
169  char *buf, *cp, *next;
170  recipe *formula = NULL;
171  recipelist *fl;
172  linked_char *tmp;
173  int value;
174 
175  if (!formulalist)
177 
178  while ((buf = bufferreader_next_line(reader)) != NULL) {
179  if (*buf == '#' || *buf == '\0')
180  continue;
181  cp = buf;
182  while (*cp == ' ') /* Skip blanks */
183  cp++;
184 
185  if (!strncmp(cp, "Remove ", 7)) {
186  if (strcmp(cp + 7, "*") == 0) {
189  } else {
190  LOG(llevError, "Recipes: only '*' is accepted for 'Remove' at %s:%zu\n", filename, bufferreader_current_line(reader));
191  }
192  continue;
193  }
194  if (!strncmp(cp, "Object", 6)) {
195  formula = get_empty_formula();
196  formula->title = add_string(strchr(cp, ' ')+1);
197  } else if (formula == NULL) {
198  LOG(llevError, "recipe.c: First key in formulae file %s is not \"Object\".\n", filename);
200  } else if (!strncmp(cp, "keycode", 7)) {
201  formula->keycode = add_string(strchr(cp, ' ')+1);
202  } else if (sscanf(cp, "trans %d", &value)) {
203  formula->transmute = value;
204  } else if (sscanf(cp, "yield %d", &value)) {
205  formula->yield = value;
206  } else if (sscanf(cp, "chance %d", &value)) {
207  formula->chance = value;
208  } else if (sscanf(cp, "exp %d", &value)) {
209  formula->exp = value;
210  } else if (sscanf(cp, "diff %d", &value)) {
211  formula->diff = value;
212  } else if (!strncmp(cp, "ingred", 6)) {
213  int numb_ingred;
214  formula->ingred_count = 1;
215  cp = strchr(cp, ' ')+1;
216  do {
217  if ((next = strchr(cp, ',')) != NULL) {
218  *(next++) = '\0';
219  formula->ingred_count++;
220  }
221  tmp = (linked_char *)malloc(sizeof(linked_char));
222  /* trim the string */
223  while (*cp == ' ')
224  cp++;
225  while (*cp != '\0' && cp[strlen(cp) - 1] == ' ')
226  cp[strlen(cp) - 1] = '\0';
227  tmp->name = add_string(cp);
228  tmp->next = formula->ingred;
229  formula->ingred = tmp;
230  /* each ingredient's ASCII value is coadded. Later on this
231  * value will be used allow us to search the formula lists
232  * quickly for the right recipe.
233  */
234  formula->index += strtoint(cp);
235  } while ((cp = next) != NULL);
236  /* now find the correct (# of ingred ordered) formulalist */
237  numb_ingred = formula->ingred_count;
238  fl = formulalist;
239  while (numb_ingred != 1) {
240  if (!fl->next)
241  fl->next = init_recipelist();
242  fl = fl->next;
243  numb_ingred--;
244  }
245  formula->next = fl->items;
246  fl->items = formula;
247  } else if (!strncmp(cp, "arch", 4)) {
248  build_stringlist(strchr(cp, ' ')+1, &formula->arch_name, &formula->arch_names);
249  } else if (!strncmp(cp, "skill", 5)) {
250  formula->skill = add_string(strchr(cp, ' ')+1);
251  } else if (!strncmp(cp, "cauldron", 8)) {
252  formula->cauldron = add_string(strchr(cp, ' ')+1);
253  } else if (!strncmp(cp, "failure_arch ", 13)) {
254  formula->failure_arch = add_string(strchr(cp, ' ')+1);
255  } else if (!strncmp(cp, "failure_message ", 16)) {
256  formula->failure_message = add_string(strchr(cp, ' ')+1);
257  } else if (sscanf(cp, "min_level %d", &value)) {
258  formula->min_level = value;
259  } else if (!strncmp(cp, "tool ", 5)) {
260  build_stringlist(strchr(cp, ' ')+1, &formula->tool, &formula->tool_size);
261  } else if (sscanf(cp, "combination %d", &value)) {
262  formula->is_combination = value ? 1 : 0;
263  } else
264  LOG(llevError, "Unknown input in file %s: %s\n", filename, buf);
265  }
266  /* Set the total chance and count for each formula list.
267  * This needs to be done at the end to avoid dependancies on the field order in the file
268  */
269  for (fl = formulalist; fl; fl = fl->next) {
270  fl->total_chance = 0;
271  fl->number = 0;
272  for (formula = fl->items; formula; formula = formula->next) {
273  fl->total_chance += formula->chance;
274  fl->number++;
275  }
276  }
277  LOG(llevDebug, "done.\n");
278 }
279 
294 void check_formulae(void) {
295  recipelist *fl;
296  recipe *check, *formula;
297  int numb = 1, tool_match;
298  size_t tool_i,tool_j;
299 
300  LOG(llevDebug, "Checking formulae lists...\n");
301 
302  for (fl = formulalist; fl != NULL; fl = fl->next) {
303  for (formula = fl->items; formula != NULL; formula = formula->next) {
304  for (check = formula->next; check != NULL; check = check->next)
305  /* If one recipe has a tool and another a caudron, we should be able to handle it */
306  if (check->index == formula->index &&
307  ((check->cauldron && formula->cauldron && strcmp(check->cauldron, formula->cauldron) == 0) ||
308  (check->tool_size == formula->tool_size && check->tool_size > 0))) {
309  /* Check the tool list to make sure they have no matches */
310  if (check->tool && formula->tool)
311  {
312  tool_match = 0;
313  for (tool_i = 0; tool_i < formula->tool_size; ++tool_i)
314  /* If it turns out these lists are sorted, then we could optimize this better. */
315  for (tool_j = 0; tool_j < check->tool_size; ++tool_j)
316  if (strcmp(formula->tool[tool_i], check->tool[tool_j]) == 0) {
317  tool_match = 1;
318  break; /* TODO: break out of the double loop */
319  }
320  }
321  else
322  tool_match = 1; /* If we get here, we matched on the cauldron */
323  /* Check to see if we have a denoted match */
324  if (tool_match) {
325  /* if the recipes don't have the same facility, then no issue anyway. */
326  LOG(llevError, " ERROR: On %d ingred list:\n", numb);
327  LOG(llevError, "Formulae [%s] of %s and [%s] of %s have matching index id (%d)\n",
328  formula->arch_name[0], formula->title, check->arch_name[0], check->title, formula->index);
329  }
330  }
331  for (size_t idx = 0; idx < formula->arch_names; idx++) {
332  if (try_find_archetype(formula->arch_name[idx]) == NULL) {
333  LOG(llevError, "Formulae %s of %s (%d ingredients) references non existent archetype %s\n",
334  formula->arch_name[0], formula->title, numb, formula->arch_name[idx]);
335  }
336  }
337  }
338  numb++;
339  }
340 
341  LOG(llevDebug, "done checking.\n");
342 }
343 
351 void dump_alchemy(void) {
352  recipelist *fl = formulalist;
353  recipe *formula = NULL;
354  linked_char *next;
355  int num_ingred = 1;
356 
357  fprintf(logfile, "\n");
358  while (fl) {
359  fprintf(logfile, "\n Formulae with %d ingredient%s %d Formulae with total_chance=%d\n", num_ingred, num_ingred > 1 ? "s." : ".", fl->number, fl->total_chance);
360  for (formula = fl->items; formula != NULL; formula = formula->next) {
361  const artifact *art = NULL;
362  char buf[MAX_BUF];
363  size_t i;
364 
365  for (i = 0; i < formula->arch_names; i++) {
366  const char *string = formula->arch_name[i];
367 
368  if (try_find_archetype(string) != NULL) {
369  art = locate_recipe_artifact(formula, i);
370  if (!art && strcmp(formula->title, "NONE"))
371  LOG(llevError, "Formula %s has no artifact\n", formula->title);
372  else {
373  if (strcmp(formula->title, "NONE"))
374  snprintf(buf, sizeof(buf), "%s of %s", string, formula->title);
375  else
376  strlcpy(buf, string, sizeof(buf));
377  fprintf(logfile, "%-30s(%d) bookchance %3d ", buf, formula->index, formula->chance);
378  fprintf(logfile, "skill %s", formula->skill);
379  fprintf(logfile, "\n");
380  if (formula->ingred != NULL) {
381  int nval = 0, tval = 0;
382  fprintf(logfile, "\tIngred: ");
383  for (next = formula->ingred; next != NULL; next = next->next) {
384  if (nval != 0)
385  fprintf(logfile, ",");
386  fprintf(logfile, "%s(%d)", next->name, (nval = strtoint(next->name)));
387  tval += nval;
388  }
389  fprintf(logfile, "\n");
390  if (tval != formula->index)
391  fprintf(logfile, "WARNING:ingredient list and formula values not equal.\n");
392  }
393  if (formula->skill != NULL)
394  fprintf(logfile, "\tSkill Required: %s", formula->skill);
395  if (formula->cauldron != NULL)
396  fprintf(logfile, "\tCauldron: %s\n", formula->cauldron);
397  fprintf(logfile, "\tDifficulty: %d\t Exp: %d\n", formula->diff, formula->exp);
398  }
399  } else
400  LOG(llevError, "Can't find archetype:%s for formula %s\n", string, formula->title);
401  }
402  }
403  fprintf(logfile, "\n");
404  fl = fl->next;
405  num_ingred++;
406  }
407 }
408 
423 archetype *find_treasure_by_name(const treasure *t, const char *name, int depth) {
424  treasurelist *tl;
425  archetype *at;
426 
427  if (depth > 10)
428  return NULL;
429 
430  while (t != NULL) {
431  if (t->name != NULL) {
432  tl = find_treasurelist(t->name);
433  at = find_treasure_by_name(tl->items, name, depth+1);
434  if (at != NULL)
435  return at;
436  } else {
437  if (!strcasecmp(t->item->clone.name, name))
438  return t->item;
439  }
440  if (t->next_yes != NULL) {
441  at = find_treasure_by_name(t->next_yes, name, depth);
442  if (at != NULL)
443  return at;
444  }
445  if (t->next_no != NULL) {
446  at = find_treasure_by_name(t->next_no, name, depth);
447  if (at != NULL)
448  return at;
449  }
450  t = t->next;
451  }
452  return NULL;
453 }
454 
474 static long recipe_find_ingredient_cost(const char *name) {
475  long mult;
476  const char *cp;
477  char part1[100];
478  char part2[100];
479 
480  /* same as atoi(), but skip number */
481  mult = 0;
482  while (isdigit(*name)) {
483  mult = 10*mult+(*name-'0');
484  name++;
485  }
486  if (mult > 0)
487  name++;
488  else
489  mult = 1;
490  /* first, try to match the name of an archetype */
491 
492  long value = 0;
493  bool found = false;
494  getManager()->archetypes()->each([&value, &found, &name, &part1] (const archetype *at) {
495  if (found) {
496  return;
497  }
498 
499  if (at->clone.title != NULL) {
500  /* inefficient, but who cares? */
501  snprintf(part1, sizeof(part1), "%s %s", at->clone.name, at->clone.title);
502  if (!strcasecmp(part1, name)) {
503  value = at->clone.value;
504  found = true;
505  return;
506  }
507  }
508  if (!strcasecmp(at->clone.name, name)) {
509  value = at->clone.value;
510  found = true;
511  return;
512  }
513  });
514  if (found) {
515  return mult * value;
516  }
517 
518  /* second, try to match an artifact ("arch of something") */
519  cp = strstr(name, " of ");
520  if (cp != NULL) {
521  safe_strncpy(part1, name, sizeof(part1));
522  part1[cp-name] = '\0';
523  safe_strncpy(part2, cp + 4, sizeof(part2));
524  getManager()->archetypes()->each([&value, &found, &part1, &part2] (const archetype *at) {
525  if (found) {
526  return;
527  }
528 
529  if (!strcasecmp(at->clone.name, part1) && at->clone.title == NULL) {
530  /* find the first artifact derived from that archetype (same type) */
531  for (auto al = first_artifactlist; al != NULL; al = al->next) {
532  if (al->type == at->clone.type) {
533  for (auto art = al->items; art != NULL; art = art->next) {
534  if (!strcasecmp(art->item->name, part2)) {
535  value = at->clone.value * art->item->value;
536  found = true;
537  return;
538  }
539  }
540  }
541  }
542  }
543  });
544  }
545  if (found) {
546  return mult * value;
547  }
548 
549  /* third, try to match a body part ("arch's something") */
550  cp = strstr(name, "'s ");
551  if (cp != NULL) {
552  safe_strncpy(part1, name, sizeof(part1));
553  part1[cp-name] = '\0';
554  safe_strncpy(part2, cp + 3, sizeof(part2));
555  /* examine all archetypes matching the first part of the name */
556  getManager()->archetypes()->each([&value, &found, &part1, &part2] (const archetype *at) {
557  if (found) {
558  return;
559  }
560  if (!strcasecmp(at->clone.name, part1) && at->clone.title == NULL) {
561  if (at->clone.randomitems != NULL) {
562  auto at2 = find_treasure_by_name(at->clone.randomitems->items, part2, 0);
563  if (at2 != NULL) {
564  value = at2->clone.value * isqrt(at->clone.level * 2);
565  found = true;
566  return;
567  }
568  }
569  }
570  });
571  }
572  if (found) {
573  return mult * value;
574  }
575 
576  /* failed to find any matching items -- formula should be checked */
577  LOG(llevError, "Couldn't find cost for ingredient %s\n", name);
578  return -1;
579 }
580 
589 void dump_alchemy_costs(void) {
590  recipelist *fl = formulalist;
591  recipe *formula = NULL;
592  linked_char *next;
593  int num_ingred = 1;
594  int num_errors = 0;
595  long cost;
596  long tcost;
597 
598  fprintf(logfile, "\n");
599  while (fl) {
600  fprintf(logfile, "\n Formulae with %d ingredient%s %d Formulae with total_chance=%d\n", num_ingred, num_ingred > 1 ? "s." : ".", fl->number, fl->total_chance);
601  for (formula = fl->items; formula != NULL; formula = formula->next) {
602  const artifact *art = NULL;
603  const archetype *at = NULL;
604  char buf[MAX_BUF];
605  size_t i;
606 
607  for (i = 0; i < formula->arch_names; i++) {
608  const char *string = formula->arch_name[i];
609 
610  if ((at = try_find_archetype(string)) != NULL) {
611  art = locate_recipe_artifact(formula, i);
612  if (!art && strcmp(formula->title, "NONE"))
613  LOG(llevError, "Formula %s has no artifact\n", formula->title);
614  else {
615  if (!strcmp(formula->title, "NONE"))
616  strlcpy(buf, string, sizeof(buf));
617  else
618  snprintf(buf, sizeof(buf), "%s of %s", string, formula->title);
619  fprintf(logfile, "\n%-40s bookchance %3d skill %s\n", buf, formula->chance, formula->skill);
620  if (formula->ingred != NULL) {
621  tcost = 0;
622  for (next = formula->ingred; next != NULL; next = next->next) {
624  if (cost < 0)
625  num_errors++;
626  fprintf(logfile, "\t%-33s%5ld\n", next->name, cost);
627  if (cost < 0 || tcost < 0)
628  tcost = -1;
629  else
630  tcost += cost;
631  }
632  if (art != NULL && art->item != NULL)
633  cost = at->clone.value*art->item->value;
634  else
635  cost = at->clone.value;
636  fprintf(logfile, "\t\tBuying result costs: %5ld", cost);
637  if (formula->yield > 1) {
638  fprintf(logfile, " to %ld (max %d items)\n", cost*formula->yield, formula->yield);
639  cost = cost*(formula->yield+1L)/2L;
640  } else
641  fprintf(logfile, "\n");
642  fprintf(logfile, "\t\tIngredients cost: %5ld\n\t\tComment: ", tcost);
643  if (tcost < 0)
644  fprintf(logfile, "Could not find some ingredients. Check the formula!\n");
645  else if (tcost > cost)
646  fprintf(logfile, "Ingredients are much too expensive. Useless formula.\n");
647  else if (tcost*2L > cost)
648  fprintf(logfile, "Ingredients are too expensive.\n");
649  else if (tcost*10L < cost)
650  fprintf(logfile, "Ingredients are too cheap.\n");
651  else
652  fprintf(logfile, "OK.\n");
653  }
654  }
655  } else
656  LOG(llevError, "Can't find archetype:%s for formula %s\n", string, formula->title);
657  }
658  }
659  fprintf(logfile, "\n");
660  fl = fl->next;
661  num_ingred++;
662  }
663  if (num_errors > 0)
664  fprintf(logfile, "WARNING: %d objects required by the formulae do not exist in the game.\n", num_errors);
665 }
666 
675 static const char *ingred_name(const char *name) {
676  const char *cp = name;
677 
678  if (atoi(cp))
679  cp = strchr(cp, ' ')+1;
680  return cp;
681 }
682 
691 static int numb_ingred(const char *buf) {
692  int numb;
693 
694  if ((numb = atoi(buf)))
695  return numb;
696  else
697  return 1;
698 }
699 
710 int strtoint(const char *buf) {
711  const char *cp = ingred_name(buf);
712  int val = 0, len = strlen(cp), mult = numb_ingred(buf);
713 
714  while (len) {
715  val += tolower(*cp);
716  cp++; len--;
717  }
718  return val*mult;
719 }
720 
731 const artifact *locate_recipe_artifact(const recipe *rp, size_t idx) {
732  object *item = create_archetype(rp->arch_name[idx]);
733  const artifactlist *at = NULL;
734  const artifact *art = NULL;
735 
736  if (!item)
737  return (artifact *)NULL;
738 
739  if ((at = find_artifactlist(item->type)))
740  for (art = at->items; art; art = art->next)
741  if (!strcmp(art->item->name, rp->title) && legal_artifact_combination(item, art))
742  break;
743 
745 
746  return art;
747 }
748 
756  recipelist *fl = NULL;
757  int number = 0, roll = 0;
758 
759  /* first, determine # of recipelist we have */
760  for (fl = get_formulalist(1); fl; fl = fl->next)
761  number++;
762 
763  /* now, randomly choose one */
764  if (number > 0)
765  roll = RANDOM()%number;
766 
767  fl = get_formulalist(1);
768  while (roll && fl) {
769  if (fl->next)
770  fl = fl->next;
771  else
772  break;
773  roll--;
774  }
775  if (!fl) /* failed! */
776  LOG(llevError, "get_random_recipelist(): no recipelists found!\n");
777  else if (fl->total_chance == 0)
778  fl = get_random_recipelist();
779 
780  return fl;
781 }
782 
792  recipelist *fl = rpl;
793  recipe *rp = NULL;
794  int r = 0;
795 
796  /* looks like we have to choose a random one */
797  if (fl == NULL)
798  if ((fl = get_random_recipelist()) == NULL)
799  return rp;
800 
801  if (fl->total_chance > 0) {
802  r = RANDOM()%fl->total_chance;
803  for (rp = fl->items; rp; rp = rp->next) {
804  r -= rp->chance;
805  if (r < 0)
806  break;
807  }
808  }
809  return rp;
810 }
811 
815 void free_all_recipes(void) {
816  recipelist *fl, *flnext;
817  recipe *formula = NULL, *next;
818  linked_char *lchar, *charnext;
819 
820  LOG(llevDebug, "Freeing all the recipes\n");
821  for (fl = formulalist; fl != NULL; fl = flnext) {
822  flnext = fl->next;
823 
824  for (formula = fl->items; formula != NULL; formula = next) {
825  next = formula->next;
826 
827  free(formula->arch_name[0]);
828  free(formula->arch_name);
829  if (formula->title)
830  free_string(formula->title);
831  if (formula->skill)
832  free_string(formula->skill);
833  if (formula->cauldron)
834  free_string(formula->cauldron);
835  if (formula->failure_arch)
836  free_string(formula->failure_arch);
837  if (formula->failure_message)
838  free_string(formula->failure_message);
839  for (lchar = formula->ingred; lchar; lchar = charnext) {
840  charnext = lchar->next;
841  free_string(lchar->name);
842  free(lchar);
843  }
844  if (formula->tool)
845  free(formula->tool[0]);
846  free(formula->tool);
847  free(formula);
848  }
849  free(fl);
850  }
851  formulalist = NULL;
852 }
853 
865 static void build_stringlist(const char *str, char ***result_list, size_t *result_size) {
866  char *dup;
867  char *p;
868  size_t size;
869  size_t i;
870 
871  dup = strdup_local(str);
872  if (dup == NULL)
874 
875  size = 0;
876  for (p = strtok(dup, ","); p != NULL; p = strtok(NULL, ","))
877  size++;
878 
879  assert(size > 0);
880  *result_list = static_cast<char **>(malloc(sizeof(**result_list) * size));
881  if (*result_list == NULL)
883  *result_size = size;
884 
885  for (i = 0; i < size; i++) {
886  (*result_list)[i] = dup;
887  dup = dup+strlen(dup)+1;
888  }
889 }
890 
898 recipe *find_recipe_for_tool(const char *tool, recipe *from) {
899  size_t t;
901  recipe *test = from ? from->next : list->items;
902 
903  while (list) {
904  while (test) {
905  for (t = 0; t < test->tool_size; t++) {
906  if (strcmp(test->tool[t], tool) == 0) {
907  return test;
908  }
909  }
910  test = test->next;
911  }
912 
913  list = list->next;
914  }
915 
916  return NULL;
917 }
918 
924 const Face *recipe_get_face(const recipe *rp) {
925  const artifact *art;
926  archetype *arch;
927  object *item;
928  const Face *face;
929 
930  if (rp->arch_names == 0)
931  return NULL;
932 
934  if (arch == NULL) {
935  return NULL;
936  }
937  if (strcmp(rp->title, "NONE") == 0) {
938  return arch->clone.face;
939  }
940 
941  art = locate_recipe_artifact(rp, 0);
942  if (art == NULL)
943  return arch->clone.face;
944 
945  face = arch->clone.face;
949  if (item->face != NULL && item->face != blank_face)
950  face = item->face;
952 
953  return face;
954 }
recipestruct::arch_names
size_t arch_names
Definition: recipe.h:12
find_recipe_for_tool
recipe * find_recipe_for_tool(const char *tool, recipe *from)
Definition: recipe.cpp:898
give.next
def next
Definition: give.py:44
Face
Definition: face.h:14
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:534
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
get_formulalist
recipelist * get_formulalist(int i)
Definition: recipe.cpp:97
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Definition: bufferreader.cpp:140
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
recipestruct::yield
int yield
Definition: recipe.h:21
strdup_local
#define strdup_local
Definition: compat.h:29
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
AssetsManager.h
dump_alchemy_costs
void dump_alchemy_costs(void)
Definition: recipe.cpp:589
init_recipelist
static recipelist * init_recipelist(void)
Definition: recipe.cpp:59
obj::value
int32_t value
Definition: object.h:358
recipestruct::tool
char ** tool
Definition: recipe.h:32
get_random_recipelist
static recipelist * get_random_recipelist(void)
Definition: recipe.cpp:755
guildoracle.list
list
Definition: guildoracle.py:87
give_artifact_abilities
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.cpp:238
recipeliststruct::next
struct recipeliststruct * next
Definition: recipe.h:41
recipestruct::title
sstring title
Definition: recipe.h:11
check_recipe
static int check_recipe(const recipe *rp)
Definition: recipe.cpp:119
tolower
#define tolower(C)
Definition: c_new.cpp:30
find_treasurelist
treasurelist * find_treasurelist(const char *name)
Definition: assets.cpp:253
artifactliststruct::items
struct artifactstruct * items
Definition: artifact.h:30
Ice.tmp
int tmp
Definition: Ice.py:207
blank_face
const Face * blank_face
Definition: image.cpp:36
SEE_LAST_ERROR
@ SEE_LAST_ERROR
Definition: define.h:52
npc_dialog.filename
filename
Definition: npc_dialog.py:99
recipestruct::ingred_count
int ingred_count
Definition: recipe.h:23
recipe_find_ingredient_cost
static long recipe_find_ingredient_cost(const char *name)
Definition: recipe.cpp:474
recipeliststruct::number
int number
Definition: recipe.h:39
buf
StringBuffer * buf
Definition: readable.cpp:1611
getManager
AssetsManager * getManager()
Definition: assets.cpp:309
recipestruct::chance
int chance
Definition: recipe.h:14
treasurestruct
Definition: treasure.h:63
formulalist
static recipelist * formulalist
Definition: recipe.cpp:49
linked_char
Definition: global.h:89
archt
Definition: object.h:472
recipestruct
Definition: recipe.h:10
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1560
recipeliststruct::total_chance
int total_chance
Definition: recipe.h:38
obj::name
sstring name
Definition: object.h:317
linked_char::name
const char * name
Definition: global.h:90
rotate-tower.result
bool result
Definition: rotate-tower.py:13
check_formulae
void check_formulae(void)
Definition: recipe.cpp:294
artifactstruct::next
struct artifactstruct * next
Definition: artifact.h:18
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
recipestruct::cauldron
sstring cauldron
Definition: recipe.h:27
recipestruct::arch_name
char ** arch_name
Definition: recipe.h:13
make_face_from_files.str
str
Definition: make_face_from_files.py:24
recipestruct::tool_size
size_t tool_size
Definition: recipe.h:33
recipestruct::exp
int exp
Definition: recipe.h:17
numb_ingred
static int numb_ingred(const char *buf)
Definition: recipe.cpp:691
linked_char::next
struct linked_char * next
Definition: global.h:91
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1592
artifactliststruct
Definition: artifact.h:26
recipestruct::keycode
sstring keycode
Definition: recipe.h:25
logfile
FILE * logfile
Definition: init.cpp:114
recipeliststruct
Definition: recipe.h:37
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
recipestruct::failure_message
sstring failure_message
Definition: recipe.h:29
recipestruct::ingred
linked_char * ingred
Definition: recipe.h:22
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:580
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
MAX_BUF
#define MAX_BUF
Definition: define.h:35
artifactstruct
Definition: artifact.h:14
free_all_recipes
void free_all_recipes(void)
Definition: recipe.cpp:815
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.cpp:222
create_archetype
object * create_archetype(const char *name)
Definition: arch.cpp:279
free_string
void free_string(sstring str)
Definition: shstr.cpp:280
RANDOM
#define RANDOM()
Definition: define.h:644
recipestruct::skill
sstring skill
Definition: recipe.h:26
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
obj::title
sstring title
Definition: object.h:323
treasureliststruct::items
struct treasurestruct * items
Definition: treasure.h:92
check_recipes
void check_recipes()
Definition: recipe.cpp:147
Floor.t
t
Definition: Floor.py:62
get_random_recipe
recipe * get_random_recipe(recipelist *rpl)
Definition: recipe.cpp:791
bigchest.check
check
Definition: bigchest.py:10
locate_recipe_artifact
const artifact * locate_recipe_artifact(const recipe *rp, size_t idx)
Definition: recipe.cpp:731
archt::clone
object clone
Definition: object.h:476
ingred_name
static const char * ingred_name(const char *name)
Definition: recipe.cpp:675
find_treasure_by_name
archetype * find_treasure_by_name(const treasure *t, const char *name, int depth)
Definition: recipe.cpp:423
item
Definition: item.py:1
recipestruct::min_level
int min_level
Definition: recipe.h:30
autojail.value
value
Definition: autojail.py:6
dump_alchemy
void dump_alchemy(void)
Definition: recipe.cpp:351
strtoint
int strtoint(const char *buf)
Definition: recipe.cpp:710
assets.h
recipestruct::next
struct recipestruct * next
Definition: recipe.h:24
recipestruct::diff
int diff
Definition: recipe.h:16
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:230
object_give_identified_properties
void object_give_identified_properties(object *op)
Definition: item.cpp:1344
recipestruct::transmute
int transmute
Definition: recipe.h:19
init_formulae
void init_formulae(BufferReader *reader, const char *filename)
Definition: recipe.cpp:168
strcasecmp
int strcasecmp(const char *s1, const char *s2)
artifactstruct::item
object * item
Definition: artifact.h:15
recipestruct::is_combination
int is_combination
Definition: recipe.h:31
recipeliststruct::items
struct recipestruct * items
Definition: recipe.h:40
get_empty_formula
static recipe * get_empty_formula(void)
Definition: recipe.cpp:78
recipestruct::index
int index
Definition: recipe.h:18
try_find_archetype
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:274
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:533
recipestruct::failure_arch
sstring failure_arch
Definition: recipe.h:28
say.item
dictionary item
Definition: say.py:149
diamondslots.cost
int cost
Definition: diamondslots.py:21
build_stringlist
static void build_stringlist(const char *str, char ***result_list, size_t *result_size)
Definition: recipe.cpp:865
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
BufferReader
Definition: bufferreader.cpp:21
find_artifactlist
artifactlist * find_artifactlist(int type)
Definition: artifact.cpp:575
recipe_get_face
const Face * recipe_get_face(const recipe *rp)
Definition: recipe.cpp:924
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
object.h
llevDebug
@ llevDebug
Definition: logger.h:13
treasureliststruct
Definition: treasure.h:85
give.name
name
Definition: give.py:27
legal_artifact_combination
int legal_artifact_combination(const object *op, const artifact *art)
Definition: artifact.cpp:260
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.cpp:102