Crossfire Server  1.75.0
gridarta-types-convert.cpp
Go to the documentation of this file.
1 
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <assert.h>
28 
29 #include "global.h"
30 #include "define.h"
31 
32 const char *destination_dir = "../doc/Developers";
33 const char *field_dir = "fields";
34 const char *type_dir = "types";
37 typedef struct {
38  char *field;
39  char *name;
40  char *description;
42 
44 typedef struct {
45  int number;
46  char *name;
47  char *description;
48  char *use;
51  char **required;
54 
57 
58 int type_count = 0;
59 
62 
65 
67 typedef struct {
68  char *name;
69  int count;
70  char **fields;
71 } ignore_list;
72 
73 ignore_list **lists = NULL;
74 int list_count = 0;
75 
77 typedef struct {
78  char **type;
79  int *number;
80  int count;
81  char *description;
83 
85 typedef struct {
86  char *field;
90 
93 
95 typedef struct {
96  const char *field;
97  const char *code_name;
99 
101 static const flag_definition flags[] = {
102  { "alive", "FLAG_ALIVE" },
103  { "wiz", "FLAG_WIZ" },
104  { "was_wiz", "FLAG_WAS_WIZ" },
105  { "applied", "FLAG_APPLIED" },
106  { "unpaid", "FLAG_UNPAID" },
107  { "can_use_shield", "FLAG_USE_SHIELD" },
108  { "no_pick", "FLAG_NO_PICK" },
109  { "client_anim_sync", "FLAG_CLIENT_ANIM_SYNC" },
110  { "client_anim_random", "FLAG_CLIENT_ANIM_RANDOM" },
111  { "is_animated", "FLAG_ANIMATE" },
112  { "monster", "FLAG_MONSTER" },
113  { "friendly", "FLAG_FRIENDLY" },
114  { "generator", "FLAG_GENERATOR" },
115  { "is_thrown", "FLAG_IS_THROWN" },
116  { "auto_apply", "FLAG_AUTO_APPLY" },
117  { "treasure", "FLAG_TREASURE" },
118  { "player sold", "FLAG_PLAYER_SOLD" },
119  { "see_invisible", "FLAG_SEE_INVISIBLE" },
120  { "can_roll", "FLAG_CAN_ROLL" },
121  { "overlay_floor", "FLAG_OVERLAY_FLOOR" },
122  { "is_turnable", "FLAG_IS_TURNABLE" },
123  { "is_used_up", "FLAG_IS_USED_UP" },
124  { "identified", "FLAG_IDENTIFIED" },
125  { "reflecting", "FLAG_REFLECTING" },
126  { "changing", "FLAG_CHANGING" },
127  { "splitting", "FLAG_SPLITTING" },
128  { "hitback", "FLAG_HITBACK" },
129  { "startequip", "FLAG_STARTEQUIP" },
130  { "blocksview", "FLAG_BLOCKSVIEW" },
131  { "undead", "FLAG_UNDEAD" },
132  { "scared", "FLAG_SCARED" },
133  { "unaggressive", "FLAG_UNAGGRESSIVE" },
134  { "reflect_missile", "FLAG_REFL_MISSILE" },
135  { "reflect_spell", "FLAG_REFL_SPELL" },
136  { "no_magic", "FLAG_NO_MAGIC" },
137  { "no_fix_player", "FLAG_NO_FIX_PLAYER" },
138  { "is_lightable", "FLAG_IS_LIGHTABLE" },
139  { "tear_down", "FLAG_TEAR_DOWN" },
140  { "run_away", "FLAG_RUN_AWAY" },
141  { "unique", "FLAG_UNIQUE" },
142  { "no_drop", "FLAG_NO_DROP" },
143  { "can_cast_spell", "FLAG_CAST_SPELL" },
144  { "can_use_scroll", "FLAG_USE_SCROLL" },
145  { "can_use_range", "FLAG_USE_RANGE" },
146  { "can_use_bow", "FLAG_USE_BOW" },
147  { "can_use_armour", "FLAG_USE_ARMOUR" },
148  { "can_use_weapon", "FLAG_USE_WEAPON" },
149  { "can_use_ring", "FLAG_USE_RING" },
150  { "has_ready_range", "FLAG_READY_RANGE" },
151  { "has_ready_bow", "FLAG_READY_BOW" },
152  { "xrays", "FLAG_XRAYS" },
153  { "is_floor", "FLAG_IS_FLOOR" },
154  { "lifesave", "FLAG_LIFESAVE" },
155  { "no_strength", "FLAG_NO_STRENGTH" },
156  { "sleep", "FLAG_SLEEP" },
157  { "stand_still", "FLAG_STAND_STILL" },
158  { "random_movement", "FLAG_RANDOM_MOVE" },
159  { "only_attack", "FLAG_ONLY_ATTACK" },
160  { "confused", "FLAG_CONFUSED" },
161  { "stealth", "FLAG_STEALTH" },
162  { "cursed", "FLAG_CURSED" },
163  { "damned", "FLAG_DAMNED" },
164  { "see_anywhere", "FLAG_SEE_ANYWHERE" },
165  { "known_magical", "FLAG_KNOWN_MAGICAL" },
166  { "known_cursed", "FLAG_KNOWN_CURSED" },
167  { "can_use_skill", "FLAG_CAN_USE_SKILL" },
168  { "been_applied", "FLAG_BEEN_APPLIED" },
169  { "has_ready_scroll", "FLAG_READY_SCROLL" },
170  { "make_invisible", "FLAG_MAKE_INVIS" },
171  { "inv_locked", "FLAG_INV_LOCKED" },
172  { "is_wooded", "FLAG_IS_WOODED" },
173  { "is_hilly", "FLAG_IS_HILLY" },
174  { "has_ready_skill", "FLAG_READY_SKILL" },
175  { "has_ready_weapon", "FLAG_READY_WEAPON" },
176  { "no_skill_ident", "FLAG_NO_SKILL_IDENT" },
177  { "is_blind", "FLAG_BLIND" },
178  { "can_see_in_dark", "FLAG_SEE_IN_DARK" },
179  { "is_cauldron", "FLAG_IS_CAULDRON" },
180  { "no_steal", "FLAG_NO_STEAL" },
181  { "one_hit", "FLAG_ONE_HIT" },
182  { "berserk", "FLAG_BERSERK" },
183  { "neutral", "FLAG_NEUTRAL" },
184  { "no_attack", "FLAG_NO_ATTACK" },
185  { "no_damage", "FLAG_NO_DAMAGE" },
186  { "activate_on_push", "FLAG_ACTIVATE_ON_PUSH" },
187  { "activate_on_release", "FLAG_ACTIVATE_ON_RELEASE" },
188  { "is_water", "FLAG_IS_WATER" },
189  { "use_content_on_gen", "FLAG_CONTENT_ON_GEN" },
190  { "is_buildable", "FLAG_IS_BUILDABLE" },
191  { "blessed", "FLAG_BLESSED" },
192  { "known_blessed", "FLAG_KNOWN_BLESSED" },
193  { NULL, NULL }
194 };
195 
197 const flag_definition *find_flag(const char *name) {
198  int flag;
199 
200  for (flag = 0; flags[flag].field; flag++)
201  if (!strcmp(flags[flag].field, name))
202  return &flags[flag];
203  return NULL;
204 }
205 
206 typedef struct {
207  const char *code_name;
208  int value;
209 } type_name;
210 
211 static type_name type_names[] = {
212  { "PLAYER", PLAYER },
213  { "TRANSPORT", TRANSPORT },
214  { "ROD", ROD },
215  { "TREASURE", TREASURE },
216  { "POTION", POTION },
217  { "FOOD", FOOD },
218  { "POISON", POISON },
219  { "BOOK", BOOK },
220  { "CLOCK", CLOCK },
221  { "ARROW", ARROW },
222  { "BOW", BOW },
223  { "WEAPON", WEAPON },
224  { "ARMOUR", ARMOUR },
225  { "PEDESTAL", PEDESTAL },
226  { "ALTAR", ALTAR },
227  { "LOCKED_DOOR", LOCKED_DOOR },
228  { "SPECIAL_KEY", SPECIAL_KEY },
229  { "MAP", MAP },
230  { "DOOR", DOOR },
231  { "KEY", KEY },
232  { "TIMED_GATE", TIMED_GATE },
233  { "TRIGGER", TRIGGER },
234  { "GRIMREAPER", GRIMREAPER },
235  { "MAGIC_EAR", MAGIC_EAR },
236  { "TRIGGER_BUTTON", TRIGGER_BUTTON },
237  { "TRIGGER_ALTAR", TRIGGER_ALTAR },
238  { "TRIGGER_PEDESTAL", TRIGGER_PEDESTAL },
239  { "SHIELD", SHIELD },
240  { "HELMET", HELMET },
241  { "MONEY", MONEY },
242  { "CLASS", CLASS },
243  { "AMULET", AMULET },
244  { "PLAYERMOVER", PLAYERMOVER },
245  { "TELEPORTER", TELEPORTER },
246  { "CREATOR", CREATOR },
247  { "SKILL", SKILL },
248  { "EARTHWALL", EARTHWALL },
249  { "GOLEM", GOLEM },
250  { "THROWN_OBJ", THROWN_OBJ },
251  { "BLINDNESS", BLINDNESS },
252  { "GOD", GOD },
253  { "DETECTOR", DETECTOR },
254  { "TRIGGER_MARKER", TRIGGER_MARKER },
255  { "DEAD_OBJECT", DEAD_OBJECT },
256  { "DRINK", DRINK },
257  { "MARKER", MARKER },
258  { "HOLY_ALTAR", HOLY_ALTAR },
259  { "PLAYER_CHANGER", PLAYER_CHANGER },
260  { "BATTLEGROUND", BATTLEGROUND },
261  { "PEACEMAKER", PEACEMAKER },
262  { "GEM", GEM },
263  { "FIREWALL", FIREWALL },
264  { "CHECK_INV", CHECK_INV },
265  { "MOOD_FLOOR", MOOD_FLOOR },
266  { "EXIT", EXIT },
267  { "ENCOUNTER", ENCOUNTER },
268  { "SHOP_FLOOR", SHOP_FLOOR },
269  { "SHOP_MAT", SHOP_MAT },
270  { "RING", RING },
271  { "FLOOR", FLOOR },
272  { "FLESH", FLESH },
273  { "INORGANIC", INORGANIC },
274  { "SKILL_TOOL", SKILL_TOOL },
275  { "LIGHTER", LIGHTER },
276  { "WALL", WALL },
277  { "MISC_OBJECT", MISC_OBJECT },
278  { "MONSTER", MONSTER },
279  { "LAMP", LAMP },
280  { "DUPLICATOR", DUPLICATOR },
281  { "SPELLBOOK", SPELLBOOK },
282  { "CLOAK", CLOAK },
283  { "SPINNER", SPINNER },
284  { "GATE", GATE },
285  { "BUTTON", BUTTON },
286  { "CF_HANDLE", CF_HANDLE },
287  { "HOLE", HOLE },
288  { "TRAPDOOR", TRAPDOOR },
289  { "SIGN", SIGN },
290  { "BOOTS", BOOTS },
291  { "GLOVES", GLOVES },
292  { "SPELL", SPELL },
293  { "SPELL_EFFECT", SPELL_EFFECT },
294  { "CONVERTER", CONVERTER },
295  { "BRACERS", BRACERS },
296  { "POISONING", POISONING },
297  { "SAVEBED", SAVEBED },
298  { "WAND", WAND },
299  { "SCROLL", SCROLL },
300  { "DIRECTOR", DIRECTOR },
301  { "GIRDLE", GIRDLE },
302  { "FORCE", FORCE },
303  { "POTION_RESIST_EFFECT", POTION_RESIST_EFFECT },
304  { "EVENT_CONNECTOR", EVENT_CONNECTOR },
305  { "CLOSE_CON", CLOSE_CON },
306  { "CONTAINER", CONTAINER },
307  { "ARMOUR_IMPROVER", ARMOUR_IMPROVER },
308  { "WEAPON_IMPROVER", WEAPON_IMPROVER },
309  { "SKILLSCROLL", SKILLSCROLL },
310  { "DEEP_SWAMP", DEEP_SWAMP },
311  { "IDENTIFY_ALTAR", IDENTIFY_ALTAR },
312  { "SHOP_INVENTORY", SHOP_INVENTORY },
313  { "RUNE", RUNE },
314  { "TRAP", TRAP },
315  { "POWER_CRYSTAL", POWER_CRYSTAL },
316  { "CORPSE", CORPSE },
317  { "DISEASE", DISEASE },
318  { "SYMPTOM", SYMPTOM },
319  { "BUILDER", BUILDER },
320  { "MATERIAL", MATERIAL },
321  { NULL, 0 }
322 };
323 
325  type_attribute *ret = static_cast<type_attribute *>(calloc(1, sizeof(type_attribute)));
326  ret->field = strdup(attr->field);
327  ret->name = strdup(attr->name);
328  ret->description = strdup(attr->description);
329  return ret;
330 }
331 
333  free(attr->field);
334  free(attr->name);
335  free(attr->description);
336  free(attr);
337 }
338 
343 type_attribute *get_attribute_for_type(type_definition *type, const char *attribute, int clean) {
344  type_attribute *ret;
345  int test;
346 
347  for (test = 0; test < type->attribute_count; test++) {
348  if (!strcmp(type->attributes[test]->field, attribute)) {
349  ret = type->attributes[test];
350  if (clean) {
351  free(ret->name);
352  ret->name = NULL;
353  free(ret->description);
354  ret->description = NULL;
355  }
356  return ret;
357  }
358  }
359  ret = static_cast<type_attribute *>(calloc(1, sizeof(type_attribute)));
360  ret->field = strdup(attribute);
361 
362  type->attribute_count++;
363  type->attributes = static_cast<type_attribute **>(realloc(type->attributes, type->attribute_count*sizeof(type_attribute *)));
364  type->attributes[type->attribute_count-1] = ret;
365 
366  return ret;
367 }
368 
369 void copy_attributes(const type_definition *source, type_definition *type) {
370  int attr;
371  type_attribute *add;
372 
373  assert(source);
374  if (source->attribute_count == 0)
375  return;
376 
377  for (attr = 0; attr < source->attribute_count; attr++) {
378  add = get_attribute_for_type(type, source->attributes[attr]->field, 1);
379  add->name = strdup(source->attributes[attr]->name);
380  if (source->attributes[attr]->description)
381  add->description = strdup(source->attributes[attr]->description);
382  }
383 }
384 
386  if (!default_type)
387  return;
388  copy_attributes(default_type, type);
389 }
390 
395  type_definition *ret = static_cast<type_definition *>(calloc(1, sizeof(type_definition)));
396 
397  ret->attribute_count = 0;
398  ret->attributes = NULL;
399  assert(ret->description == NULL);
400 
401  if (default_type)
403 
404  return ret;
405 }
406 
411  int type;
412 
413  for (type = 0; type < type_count; type++) {
414  if (!strcmp(types[type]->name, name))
415  return types[type];
416  }
417  printf("type not found: %s\n", name);
418  return NULL;
419 }
420 
422 int sort_type_attribute(const void *a, const void *b) {
423  const type_attribute **la = (const type_attribute **)a;
424  const type_attribute **lb = (const type_attribute **)b;
425 
426  return strcmp((*la)->name, (*lb)->name);
427 }
428 
429 ignore_list *find_ignore_list(const char *name) {
430  int list;
431 
432  for (list = 0; list < list_count; list++) {
433  if (strcmp(lists[list]->name, name) == 0)
434  return lists[list];
435  }
436  return NULL;
437 }
438 
442 char *read_line(char *buffer, int size, FILE *file) {
443  return fgets(buffer, 200, file);
444 }
445 
447 void ignore_attribute(type_definition *type, const char *attribute) {
448  int find;
449 
450  for (find = 0; find < type->attribute_count; find++) {
451  if (!strcmp(attribute, type->attributes[find]->field)) {
452  /*printf("rem %s from %s\n", list->fields[attr], type->name);*/
453  free_attribute(type->attributes[find]);
454  if (find < type->attribute_count-1)
455  type->attributes[find] = type->attributes[type->attribute_count-1];
456  type->attribute_count--;
457  return;
458  }
459  }
460 }
461 
464  int attr;
465 
466  if (!list) {
467  printf("empty ignore list?\n");
468  return;
469  }
470 
471  for (attr = 0; attr < list->count; attr++) {
472  ignore_attribute(type, list->fields[attr]);
473  }
474 }
475 
477 void add_required_parameter(type_definition *type, const char *buf) {
478  char *sn, *en, *sv, *ev;
479  char value[200], name[200], temp[200];
480  const flag_definition *flag;
481 
482  if (type == fallback_type)
483  /* the "Misc" type has dummy requirements, don't take that into account. */
484  return;
485 
486  sn = strstr(const_cast<char *>(buf), "arch");
487  if (!sn)
488  return;
489  sn = strchr(sn, '"');
490  en = strchr(sn+1, '"');
491  sv = strstr(const_cast<char *>(buf), "value");
492  sv = strchr(sv, '"');
493  ev = strchr(sv+1, '"');
494 
495  name[en-sn-1] = '\0';
496  strncpy(name, sn+1, en-sn-1);
497  value[ev-sv-1] = '\0';
498  strncpy(value, sv+1, ev-sv-1);
499 
500  type->require_count++;
501  type->required = static_cast<char **>(realloc(type->required, type->require_count*sizeof(char *)));
502 
503  flag = find_flag(name);
504  if (flag)
505  snprintf(temp, 200, "@ref %s %s", flag->code_name, strcmp(value, "0") ? "set" : "unset");
506  else
507  snprintf(temp, 200, "@ref object::%s = %s", name, value);
508  type->required[type->require_count-1] = strdup(temp);
509 }
510 
512 void read_type(type_definition *type, FILE *file, const char *block_end) {
513  char buf[200], tmp[200];
514  char *find, *end;
515  type_attribute *attr;
516 
517  while (read_line(buf, 200, file)) {
518  if (strstr(buf, block_end) != NULL) {
519  if (type->attribute_count)
520  qsort(type->attributes, type->attribute_count, sizeof(type_attribute *), sort_type_attribute);
521  return;
522  }
523  if (strstr(buf, "<description>") != NULL) {
524  while (read_line(buf, 200, file)) {
525  if (strstr(buf, "</description>") != NULL)
526  break;
527 
528  if (type->description) {
529  type->description = static_cast<char *>(realloc(type->description, strlen(type->description)+strlen(buf)+1));
530  strcat(type->description, buf);
531  }
532  else
533  type->description = strdup(buf);
534  }
535  find = strstr(type->description, "]]>");
536  if (find)
537  type->description[find-type->description] = '\0';
538  while (type->description[strlen(type->description)-1] == '\n')
539  type->description[strlen(type->description)-1] = '\0';
540  /*printf(" => desc = %s\n", type->description);*/
541  }
542 
543  if (strstr(buf, "<ignore_list") != NULL) {
544  find = strstr(buf, "name=");
545  if (!find)
546  return;
547  find = strchr(find+1, '"');
548  if (!find)
549  return;
550  end = strchr(find+1, '"');
551  if (!end)
552  return;
553  tmp[end-find-1] = '\0';
554  strncpy(tmp, find+1, end-find-1);
556  }
557 
558  if (strstr(buf, "<ignore>") != NULL) {
559  while (read_line(buf, 200, file)) {
560  if (strstr(buf, "</ignore>") != NULL)
561  break;
562  find = strstr(buf, "arch=");
563  if (!find)
564  continue;
565  find = strchr(find+1, '"');
566  if (!find)
567  continue;
568  end = strchr(find+1, '"');
569  if (!end)
570  continue;
571  tmp[end-find-1] = '\0';
572  strncpy(tmp, find+1, end-find-1);
573  ignore_attribute(type, tmp);
574  }
575  }
576 
577  if (strstr(buf, "<required>") != NULL) {
578  while (read_line(buf, 200, file)) {
579  if (strstr(buf, "</required>") != NULL)
580  break;
581  add_required_parameter(type, buf);
582  }
583  }
584 
585  if (strstr(buf, "<import_type") != NULL) {
586  type_definition *import;
587 
588  find = strstr(buf, "name=");
589  if (!find)
590  return;
591  find = strchr(find+1, '"');
592  if (!find)
593  return;
594  end = strchr(find+1, '"');
595  if (!end)
596  return;
597  tmp[end-find-1] = '\0';
598  strncpy(tmp, find+1, end-find-1);
599  import = find_type_definition(tmp);
600  if (import) {
601  /*printf("%s import %s\n", type->name, tmp);*/
602  copy_attributes(import, type);
603  }
604  else
605  printf("%s: import %s not found\n", type->name, tmp);
606  }
607 
608  if (strstr(buf, "<attribute") != NULL) {
609  find = strstr(buf, "arch");
610  if (!find)
611  continue;
612  find = strchr(find, '"');
613  end = strchr(find+1, '"');
614  if (end == find+1)
615  /* empty arch, meaning inventory or such, ignore. */
616  continue;
617 
618  tmp[end-find-1] = '\0';
619  strncpy(tmp, find+1, end-find-1);
620  /*printf(" => attr %s\n", tmp);*/
621 
622  find = strstr(buf, "editor");
623  if (find == NULL)
624  /* fixed or other, ignore */
625  continue;
626  attr = get_attribute_for_type(type, tmp, 1);
627  find = strchr(find, '"');
628  end = strchr(find+1, '"');
629  tmp[end-find-1] = '\0';
630  strncpy(tmp, find+1, end-find-1);
631  attr->name = strdup(tmp);
632 
633  /* Description can be empty, with end tag on the same line. */
634  if (strstr(buf, "</attribute>") == NULL && strstr(buf, "/>") == NULL) {
635  while (read_line(buf, 200, file)) {
636  if (strstr(buf, "<![CDATA[<html>") != NULL)
637  /* some data is in HTML, that's ok */
638  continue;
639  if (strstr(buf, "]]>") != NULL)
640  /* end of cdata html */
641  continue;
642  if (strstr(buf, "</attribute>") != NULL)
643  break;
644  if (attr->description) {
645  attr->description = static_cast<char *>(realloc(attr->description, strlen(attr->description)+strlen(buf)+1));
646  strcat(attr->description, buf);
647  }
648  else
649  attr->description = strdup(buf);
650  }
651  }
652  if (attr->description)
653  while (attr->description[strlen(attr->description)-1] == '\n')
654  attr->description[strlen(attr->description)-1] = '\0';
655 
656  }
657  }
658 }
659 
661  int attr;
662 
663  printf("type: %s [%d]\n", type->name, type->number);
664  printf(" attributes:\n");
665  for (attr = 0; attr < type->attribute_count; attr++) {
666  printf(" %30s: %s\n", type->attributes[attr]->field, type->attributes[attr]->name);
667  printf(" %s\n", type->attributes[attr]->description);
668  }
669 }
670 
671 void dump_types(void) {
672  int t;
673  type_definition *type;
674 
675  for (t = 0; t < type_count; t++) {
676  type = types[t];
677  dump_type(type);
678  }
679 }
680 
683  int attr;
685 
686  for (attr = 0; attr < attribute_count; attr++) {
687  if (!strcmp(attributes[attr]->field, name))
688  return attributes[attr];
689  }
690 
691  ret = static_cast<attribute_definition *>(calloc(1, sizeof(attribute_definition)));
692  attribute_count++;
693  attributes = static_cast<attribute_definition **>(realloc(attributes, attribute_count*sizeof(attribute_definition *)));
694  attributes[attribute_count-1] = ret;
695 
696  ret->field = strdup(name);
697 
698  return ret;
699 }
700 
703  int desc;
704  attribute_type *add;
705 
706  for (desc = 0; desc < attribute->type_count; desc++) {
707  if (!description && !attribute->types[desc]->description)
708  return attribute->types[desc];
709  if (description && attribute->types[desc]->description && !strcmp(description, attribute->types[desc]->description))
710  return attribute->types[desc];
711  }
712 
713  add = static_cast<attribute_type *>(calloc(1, sizeof(attribute_type)));
714  attribute->type_count++;
715  attribute->types = static_cast<attribute_type **>(realloc(attribute->types, attribute->type_count*sizeof(attribute_type)));
716  attribute->types[attribute->type_count-1] = add;
717 
718  if (description)
719  add->description = strdup(description);
720 
721  return add;
722 }
723 
724 void add_type_to_attribute(attribute_definition *attribute, type_definition *type, int attr) {
725  attribute_type *att;
726 
727  att = get_description_for_attribute(attribute, type->attributes[attr]->description);
728  att->count++;
729  att->type = static_cast<char **>(realloc(att->type, att->count*sizeof(const char *)));
730  att->number = static_cast<int *>(realloc(att->number, att->count*sizeof(int)));
731  att->type[att->count-1] = strdup(type->name);
732  att->number[att->count-1] = type->number;
733 }
734 
736 void read_ignore_list(const char *name, FILE *file) {
737  char buf[200], tmp[200];
738  char *start, *end;
739  ignore_list *list;
740 
741  /*printf("il %s:", name);*/
742  list = static_cast<ignore_list *>(calloc(1, sizeof(ignore_list)));
743  list_count++;
744  lists = static_cast<ignore_list **>(realloc(lists, list_count*sizeof(ignore_list *)));
745  lists[list_count-1] = list;
746  list->name = strdup(name);
747 
748  while (read_line(buf, 200, file)) {
749  if (strstr(buf, "</ignore_list>") != NULL) {
750  /*printf("\n");*/
751  return;
752  }
753  start = strstr(buf, "arch=");
754  if (!start)
755  continue;
756  start = strchr(start+1, '"');
757  if (!start)
758  continue;
759  end = strchr(start+1, '"');
760  if (!end)
761  continue;
762 
763  tmp[end-start-1] = '\0';
764  strncpy(tmp, start+1, end-start-1);
765  /*printf(" %s", tmp);*/
766 
767  list->count++;
768  list->fields = static_cast<char **>(realloc(list->fields, list->count*sizeof(char *)));
769  list->fields[list->count-1] = strdup(tmp);
770  }
771 }
772 
773 void dump_ignore_lists(void) {
774  int list, field;
775 
776  printf("ignore lists:\n");
777  for (list = 0; list < list_count; list++) {
778  printf(" %s:", lists[list]->name);
779  for (field = 0; field < lists[list]->count; field++)
780  printf(" %s", lists[list]->fields[field]);
781  printf("\n");
782  }
783 }
784 
786 static const char *in_living[] = {
787  "Str",
788  "Dex",
789  "Con",
790  "Wis",
791  "Cha",
792  "Int",
793  "Pow",
794  "wc",
795  "ac",
796  "hp",
797  "maxhp",
798  "sp",
799  "maxsp",
800  "grace",
801  "maxgrace",
802  "exp",
803  "food",
804  "dam",
805  "luck",
806  NULL
807 };
808 
810 static const char *custom_attributes[] = {
811  /* transports */
812  "weight_speed_ratio",
813  "base_speed",
814  "passenger_limit",
815  "face_full",
816  "anim_full",
817  /* misc */
818  "accept_alive",
819  "death_animation",
820  "face_opened",
821  "generator_code",
822  "generator_limit",
823  "generator_max_map",
824  "generator_radius",
825  "no_mood_change",
826  "on_use_yield",
827  "race_restriction",
828  "wc_increase_rate",
829  "price_adjustment",
830  "price_adjustment_buy",
831  "price_adjustment_sell",
832  "casting_requirements",
833  "identified_name",
834  "identified_name_pl",
835  "identified_face",
836  "identified_animation",
837  "identified_anim_speed",
838  "identified_anim_random",
839  "immunity_chance",
840  "elevation",
841  "blocks_prayer",
842  NULL
843 };
844 
845 int is_custom_attribute(const char *attribute) {
846  int val;
847 
848  for (val = 0; custom_attributes[val] != NULL; val++) {
849  if (!strcmp(custom_attributes[val], attribute)) {
850  return 1;
851  }
852  }
853  return 0;
854 }
855 
857 void write_attribute_reference(const char *attribute, FILE *file) {
858  const flag_definition *flag = find_flag(attribute);
859  int val;
860 
861  if (flag) {
862  fprintf(file, "%s", flag->code_name);
863  return;
864  }
865  for (val = 0; in_living[val] != NULL; val++) {
866  if (!strcmp(in_living[val], attribute)) {
867  fprintf(file, "living::%s", attribute);
868  return;
869  }
870  }
871  if (is_custom_attribute(attribute)) {
872  fprintf(file, "page_custom_attribute_%s \"%s\"", attribute, attribute);
873  return;
874  }
875  if (strstr(attribute, "resist_")) {
876  fprintf(file, "object::resist");
877  return;
878  }
879  if (!strcmp(attribute, "connected")) {
880  fprintf(file, "page_connected \"connection value\"");
881  return;
882  }
883  fprintf(file, "object::%s", attribute);
884 }
885 
888  FILE *file;
889  char buf[200];
890  int attr, req;
891 
892  snprintf(buf, 200, "%s/%s/type_%d.dox", destination_dir, type_dir, type->number);
893  file = fopen(buf, "w+");
894 
895  fprintf(file, "/**\n");
896 
897  /* auto-generate documentation for the type, so no need to change define.h */
898  if (type->number > 0) {
899  for (req = 0; type_names[req].code_name != NULL; req++) {
900  if (type_names[req].value == type->number) {
901  fprintf(file, "@var %s\nSee @ref page_type_%d\n*/\n\n/**\n", type_names[req].code_name, type->number);
902  break;
903  }
904  }
905  }
906 
907  fprintf(file, "@page page_type_%d %s\n\n", type->number, type->name);
908  fprintf(file, "%s\n\n", type->description);
909  if (type != fallback_type) {
910  fprintf(file, "\n\nType defined by:\n");
911  if (type->number && type->number < OBJECT_TYPE_MAX)
912  fprintf(file, "- @ref object::type = %d\n", type->number);
913  for (req = 0; req < type->require_count; req++)
914  fprintf(file, "- %s\n", type->required[req]);
915  }
916 
917  fprintf(file, "\n\n# Attributes\n\n");
918  fprintf(file, "<table>\n\t<tr>\n\t\t<th>Attribute</th>\n\t\t<th>Field</th>\n\t\t<th>Description</th>\n\t</tr>\n");
919  for (attr = 0; attr < type->attribute_count; attr++) {
920  fprintf(file, "\t<tr>\n\t\t<td>%s</td>\n\t\t<td>@ref ", type->attributes[attr]->name);
921  write_attribute_reference(type->attributes[attr]->field, file);
922  fprintf(file, "</td>\n\t\t<td>%s\n\t\t</td>\n\t</tr>\n", type->attributes[attr]->description ? type->attributes[attr]->description : "(no description)");
923  }
924 
925  fprintf(file, "</table>\n*/\n");
926 
927  fclose(file);
928 }
929 
931 void write_type_index(void) {
932  FILE *index;
933  int type;
934  char buf[200];
935 
936  snprintf(buf, 200, "%s/%s/types.dox", destination_dir, type_dir);
937  index = fopen(buf, "w+");
938  fprintf(index, "/**\n@page type_index Type index\n");
939 
940  fprintf(index, "Types not listed here have the attributes defined in @subpage page_type_0 \"this page\".\n\n");
941 
942  for (type = 0; type < type_count; type++) {
943  fprintf(index, "- @subpage page_type_%d \"%s (%d)\"\n", types[type]->number, types[type]->name, types[type]->number);
944  }
945 
946  fprintf(index, "*/\n");
947 
948  fclose(index);
949 }
950 
953  FILE *index;
954  int attribute;
955  char buf[200];
956 
957  snprintf(buf, 200, "%s/%s/fields.dox", destination_dir, field_dir);
958  index = fopen(buf, "w+");
959  fprintf(index, "/**\n@page field_index Field index\n");
960 
961  fprintf(index, "This page lists all attributes.\n\n");
962 
963  for (attribute = 0; attribute < attribute_count; attribute++) {
964  fprintf(index, "- @subpage ");
965  write_attribute_reference(attributes[attribute]->field, index);
966  fprintf(index, "\n");
967  }
968 
969  fprintf(index, "*/\n");
970 
971  fclose(index);
972 }
973 
976  FILE *file;
977  char buf[200];
978  int type, desc;
979  const char *end;
980 
981  snprintf(buf, 200, "%s/%s/field_%s.dox", destination_dir, field_dir, attribute->field);
982  file = fopen(buf, "w+");
983 
984  if (is_custom_attribute(attribute->field)) {
985  fprintf(file, "/**\n@page page_custom_attribute_%s %s", attribute->field, attribute->field);
986  fprintf(file, "\nThis is a @ref page_custom_attributes \"custom attribute\".\n");
987  } else {
988  if (strcmp(attribute->field, "connected") == 0)
989  fprintf(file, "/**\n@page ");
990  else
991  fprintf(file, "/**\n@fn ");
992  write_attribute_reference(attribute->field, file);
993  }
994 
995  /* resistances are special, they'll be merged in the object::resist paragraph, so specify the name. */
996  if (strstr(attribute->field, "resist_"))
997  fprintf(file, "\n@section %s %s resistance\n", attribute->field, attribute->field+7);
998  else
999  fprintf(file, "\n# Use\n");
1000 
1001  fprintf(file, "<table>\n\t<tr>\n\t\t<th>Type(s)</th>\n\t\t<th>Description</th>\n\t</tr>");
1002 
1003  for (desc = 0; desc < attribute->type_count; desc++) {
1004  assert(attribute->types[desc]->count > 0);
1005 
1006  fprintf(file, "\t<tr>\n\t\t<td>\n");
1007 
1008  for (type = 0; type < attribute->types[desc]->count; type++) {
1009  if (type < attribute->types[desc]->count-1)
1010  end = ", ";
1011  else
1012  end = "\n";
1013  fprintf(file, "@ref page_type_%d%s", attribute->types[desc]->number[type], end);
1014  }
1015  fprintf(file, "\t\t</td><td>%s</td>\n\t</tr>\n", attribute->types[desc]->description ? attribute->types[desc]->description : "(no description)");
1016  }
1017 
1018  fprintf(file, "\n*/\n");
1019 
1020  fclose(file);
1021 }
1022 
1023 int main(int argc, char **argv) {
1024  FILE *xml;
1025  int number, attr, dummy;
1026  char buf[200], tmp[200];
1027  char *start, *end;
1028  type_definition *type;
1029 
1030  if (argc < 2) {
1031  printf("Syntax: %s /path/to/Gridarta/types.xml\n", argv[0]);
1032  return 1;
1033  }
1034 
1035  /* dummy type number for special types. */
1036  dummy = OBJECT_TYPE_MAX+50;
1037 
1038  xml = fopen(argv[1], "r");
1039 
1040  if (!xml) {
1041  printf("Could not find file %s\n", argv[1]);
1042  return 1;
1043  }
1044 
1045  while (read_line(buf, 200, xml) != NULL) {
1046  if (buf[0] == '#')
1047  continue;
1048  if (strstr(buf, "<default_type>")) {
1049  default_type = get_type_definition();
1050  default_type->name = strdup("(default type)");
1051  read_type(default_type, xml, "</default_type>");
1052  continue;
1053  }
1054 
1055  if (strstr(buf, "<ignore_list") != NULL) {
1056  start = strstr(buf, "name=");
1057  start = strchr(start+1, '"');
1058  end = strchr(start+1, '"');
1059  tmp[end-start-1] = '\0';
1060  strncpy(tmp, start+1, end-start-1);
1061  read_ignore_list(tmp, xml);
1062  continue;
1063  }
1064 
1065  start = strstr(buf, "<type number");
1066  if (start) {
1067  start = strchr(start, '"');
1068  /*if (!start)
1069  break;*/
1070  end = strchr(start+1, '"');
1071  /*if (!end)
1072  break;*/
1073  tmp[end-start-1] = '\0';
1074  strncpy(tmp, start+1, end-start-1);
1075  /*printf("type %s ", tmp);*/
1076 
1077  number = atoi(tmp);
1078  start = strstr(end, "name=");
1079  start = strchr(start, '"');
1080  end = strchr(start+1, '"');
1081  tmp[end-start-1] = '\0';
1082  strncpy(tmp, start+1, end-start-1);
1083 
1084  if (!strcmp(tmp, "Misc")) {
1085  fallback_type = get_type_definition();
1086  type = fallback_type;
1087  }
1088  else {
1089  if (number == 0)
1090  number = dummy++;
1091  type = get_type_definition();
1092  type_count++;
1093  types = static_cast<type_definition **>(realloc(types, type_count*sizeof(type_definition *)));
1094  types[type_count-1] = type;
1095  }
1096 
1097 #if 0
1098  if (!number || number >= OBJECT_TYPE_MAX || types[number] != NULL) {
1099  /*printf("=> skip\n");*/
1100  while (read_line(buf, 200, xml) != NULL && strstr(buf, "</type>") == NULL)
1101  /*printf(" => skip %s\n", buf)*/;
1102  /*printf(" => end of skip\n");*/
1103  continue;
1104  }
1105 #endif
1106 
1107  type->number = number;
1108 
1109  /*printf("nom %s\n", tmp);*/
1110  type->name = strdup(tmp);
1111 
1112  read_type(type, xml, "</type>");
1113  }
1114  }
1115 
1116  free(fallback_type->description);
1117  fallback_type->description = strdup("This type regroups all types who don't have a specific definition.");
1118 
1119  for (number = 0; number < type_count; number++) {
1120  for (attr = 0; attr < types[number]->attribute_count; attr++)
1121  add_type_to_attribute(get_attribute(types[number]->attributes[attr]->field), types[number], attr);
1122  }
1123 
1124 /* dump_types();*/
1125 /* dump_type(default_type);*/
1126 /* dump_ignore_lists();*/
1127 
1128  write_type_index();
1129  for (number = 0; number < type_count; number++)
1130  write_type_file(types[number]);
1131  write_type_file(fallback_type);
1132 
1134  for (attr = 0; attr < attribute_count; attr++)
1135  write_attribute_file(attributes[attr]);
1136 
1137  fclose(xml);
1138  free(types);
1139  return 0;
1140 }
See Pedestal.
Definition: object.h:126
void read_ignore_list(const char *name, FILE *file)
Read the contents of a <ignore_list> tag.
see doc/Developers/objects
Definition: object.h:113
See Key.
Definition: object.h:132
See Ring.
Definition: object.h:190
Definition: object.h:130
void write_type_index(void)
Write index of all types.
Eneq((at)csd.uu.se): Id for close_container archetype.
Definition: object.h:234
See Bracers.
Definition: object.h:222
See Scroll.
Definition: object.h:226
static type_name type_names[]
See Cloak.
Definition: object.h:209
See Food.
Definition: object.h:117
void ignore_attributes(type_definition *type, ignore_list *list)
Remove all attributes in the specified list from the type.
See Projectile.
Definition: object.h:122
Try to find a fire/heat source to light this when applied.
Definition: object.h:256
type_definition * get_type_definition(void)
Returns a new type_definition having the default attributes.
See Holy Altar.
Definition: object.h:166
int list_count
void read_type(type_definition *type, FILE *file, const char *block_end)
Read all lines related to a type, stop when "block_end" is found on a line.
See Spellbook.
Definition: object.h:208
See Money.
Definition: object.h:142
void copy_attributes(const type_definition *source, type_definition *type)
attribute_type * get_description_for_attribute(attribute_definition *attribute, const char *description)
Gets a type description for specified attribute, create it if doesn&#39;t exist.
See Rune.
Definition: object.h:245
See Creator.
Definition: object.h:147
See Weapon.
Definition: object.h:124
See Helmet.
Definition: object.h:141
Object for applying character class modifications to someone.
Definition: object.h:143
void write_attribute_file(attribute_definition *attribute)
Write the description of a field.
See Altar Trigger.
Definition: object.h:138
See Rod.
Definition: object.h:114
See Power Crystal.
Definition: object.h:247
See Button Trigger.
Definition: object.h:137
const flag_definition * find_flag(const char *name)
Return flag if exists, NULL else.
See Drink.
Definition: object.h:162
See Girdle.
Definition: object.h:228
See Amulet.
Definition: object.h:144
Wall.
Definition: object.h:196
Duplicator/multiplier object.
Definition: object.h:207
const char * type_dir
Where the files about types will be stored.
static const char * in_living[]
Fields part of the living structure.
animal &#39;body parts&#39; -b.t.
Definition: object.h:192
Global type definitions and header inclusions.
See Boots.
Definition: object.h:217
peterm: detector is an object which notices the presense of another object and is triggered like butt...
Definition: object.h:154
See Mover.
Definition: object.h:145
See Wand & Staff.
Definition: object.h:225
See Magic Ear.
Definition: object.h:136
const char * field_dir
Where the files about the fields will be stored.
Allows the use of a skill.
Definition: object.h:194
int attribute_count
Generic item builder, see subtypes below.
Definition: object.h:251
See Trap.
Definition: object.h:246
void copy_default_attributes(type_definition *type)
type_definition * fallback_type
Dummy object type that non defined objects use.
Floor tile -> native layer 0.
Definition: object.h:191
See Shooting Weapon.
Definition: object.h:123
See Sign & Magic Mouth.
Definition: object.h:216
void write_attribute_reference(const char *attribute, FILE *file)
Write the part to the right of a @ref for the specified attribute.
See Book.
Definition: object.h:119
See Exit.
Definition: object.h:186
int main(int argc, char **argv)
battleground, by Andreas Vogl
Definition: object.h:168
inserts an invisible, weightless force into a player with a specified string.
Definition: object.h:163
const char * destination_dir
Root destination dir.
See Treasure.
Definition: object.h:115
See Special Key.
Definition: object.h:129
A real, living creature.
Definition: object.h:205
type_definition * default_type
Definitions all types have by default.
inserts an invisible, weightless force into a player with a specified string WHEN TRIGGERED...
Definition: object.h:158
See Clock.
Definition: object.h:120
type_attribute ** attributes
ignore_list ** lists
Definition: object.h:150
attribute_definition ** attributes
See Trapdoor.
Definition: object.h:215
See Potion.
Definition: object.h:116
char * read_line(char *buffer, int size, FILE *file)
See Shop Mat.
Definition: object.h:189
void dump_type(type_definition *type)
void add_required_parameter(type_definition *type, const char *buf)
Add a required parameter to the specified type.
See Spell.
Definition: object.h:219
See Handle Trigger.
Definition: object.h:134
See Locked Door.
Definition: object.h:128
type_attribute * duplicate_attribute(type_attribute *attr)
static const char * custom_attributes[]
Custom attributes we know about, to point to the right page.
int type_count
int is_custom_attribute(const char *attribute)
See Spinner.
Definition: object.h:210
See Door.
Definition: object.h:131
See Magic Wall.
Definition: object.h:173
Object owned by a player which can convert a monster into a peaceful being incapable of attack...
Definition: object.h:169
See Converter.
Definition: object.h:221
can add a skill to player&#39;s inventory -bt.
Definition: object.h:239
Lamp.
Definition: object.h:206
One type for an attribute.
See Container.
Definition: object.h:236
See Player Changer.
Definition: object.h:167
static const flag_definition flags[]
Flag mapping.
type_definition ** types
Defined types.
See Player.
Definition: object.h:112
See Poison Food.
Definition: object.h:118
See Shield.
Definition: object.h:140
See Floor (Encounter).
Definition: object.h:187
Mark Wedel (mark@pyramid.com) Shop inventories.
Definition: object.h:243
See Altar.
Definition: object.h:127
Definition: object.h:248
Also see SKILL_TOOL (74) below.
Definition: object.h:148
type_attribute * get_attribute_for_type(type_definition *type, const char *attribute, int clean)
Gets the attribute for the specified type.
See Shop Floor.
Definition: object.h:188
See Button.
Definition: object.h:212
See Gate.
Definition: object.h:211
misc.
Definition: object.h:198
Material for building.
Definition: object.h:253
See Handle.
Definition: object.h:213
See Timed Gate.
Definition: object.h:133
void dump_ignore_lists(void)
Lauwenmark: an invisible object holding a plugin event hook.
Definition: object.h:232
ignore_list * find_ignore_list(const char *name)
See Monster (Grimreaper).
Definition: object.h:135
See Gloves.
Definition: object.h:218
A force, holding the effect of a resistance potion.
Definition: object.h:230
void add_type_to_attribute(attribute_definition *attribute, type_definition *type, int attr)
void free_attribute(type_attribute *attr)
StringBuffer * buf
Definition: readable.cpp:1563
metals, minerals, dragon scales
Definition: object.h:193
See Pit.
Definition: object.h:214
const char * code_name
See Swamp.
Definition: object.h:241
One attribute in a type.
type_definition * find_type_definition(const char *name)
Used for type import.
void write_type_file(type_definition *type)
Write a type definition file.
See Jewel.
Definition: object.h:172
See Breastplate Armor.
Definition: object.h:125
One list of fields to ignore.
Definition: object.h:153
See Disease.
Definition: object.h:249
attribute_definition * get_attribute(const char *name)
Get an attribute, create it if it doesn&#39;t exist yet.
See Director.
Definition: object.h:227
See Teleporter.
Definition: object.h:146
void write_attribute_index(void)
Write the index of all attributes.
b.t.
Definition: object.h:175
void dump_types(void)
See Savebed.
Definition: object.h:224
int sort_type_attribute(const void *a, const void *b)
To sort attributes.
b.t.
Definition: object.h:174
Core defines: object types, flags, etc.
Definition: object.h:229
void ignore_attribute(type_definition *type, const char *attribute)
Remove an attribute from the type.