Crossfire Server, Trunk
bwp.c
Go to the documentation of this file.
1 /*
2  * bwp - build wiki pages
3  *
4  * This program will sort out all monster archetypes and print wiki pages
5  * for them, named 'a' through 'z'. It uses some *_template subroutines taken
6  * from Ryo's mapper.c. It should compile if installed in server/trunk/utils.
7  * Please direct all suggestions or corrections to aaron@baugher.biz (or
8  * Mhoram on #crossfire).
9  *
10  * Compile command: gcc -g -O0 bwp.c -I../include ../common/libcross.a ../socket/libsocket.a ../server/libserver.a ../types/libtypes.a -o bwp -lz -lcrypt -lm -lstdc++
11  */
12 
13 /*
14  * CrossFire, A Multiplayer game for X-windows
15  *
16  * Copyright (C) 2002-2006 Mark Wedel & Crossfire Development Team
17  * Copyright (C) 1992 Frank Tore Johansen
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 2 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32  *
33  * The authors can be reached via e-mail at crossfire-devel@real-time.com
34  */
35 
36 #define LO_NEWFILE 2
37 #define MAX_SIZE 64
38 #define NA "n/a"
39 
40 #include <time.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <global.h>
44 #include <sys/stat.h>
45 
46 char *monster_page_head; /* Head of wiki page of monsters */
47 char *monster_page_foot; /* Foot of wiki page of monsters */
48 char *monster_entry; /* A single monster entry */
49 char *monster_canuse_row; /* Can_use table row */
50 char *monster_protected_row; /* Protected table row */
51 char *monster_vulnerable_row; /* Vulnerable table row */
52 char *monster_special_row; /* Special table row */
53 char *monster_attack_row; /* Attack types table row */
54 char *monster_lore_row; /* Lore table row */
55 
56 typedef struct string_array {
57  int16_t count;
58  char **item;
59 } String_Array;
60 
70 const char *const flag_names[NUM_FLAGS+1] = {
71  "alive", "wiz", NULL, NULL, "was_wiz", "applied", "unpaid",
72  "can_use_shield", "no_pick", "client_anim_sync", "client_anim_random", /* 10 */
73  "is_animated", NULL /* slow_move */,
74  NULL /* flying */, "monster", "friendly", "generator",
75  "is_thrown", "auto_apply", "treasure", "player sold", /* 20 */
76  "see_invisible", "can_roll", "overlay_floor",
77  "is_turnable", NULL /* walk_off */, NULL /* fly_on */,
78  NULL /*fly_off*/, "is_used_up", "identified", "reflecting", /* 30 */
79  "changing", "splitting", "hitback", "startequip",
80  "blocksview", "undead", "scared", "unaggressive",
81  "reflect_missile", "reflect_spell", /* 40 */
82  "no_magic", "no_fix_player", "is_lightable", "tear_down",
83  "run_away", NULL /*pass_thru */, NULL /*can_pass_thru*/,
84  "pick_up", "unique", "no_drop", /* 50 */
85  NULL /* wizcast*/, "can_cast_spell", "can_use_scroll", "can_use_range",
86  "can_use_bow", "can_use_armour", "can_use_weapon",
87  "can_use_ring", "has_ready_range", "has_ready_bow", /* 60 */
88  "xrays", NULL, "is_floor", "lifesave", "no_strength", "sleep",
89  "stand_still", "random_movement", "only_attack", "confused", /* 70 */
90  "stealth", NULL, NULL, "cursed", "damned",
91  "see_anywhere", "known_magical", "known_cursed",
92  "can_use_skill", "been_applied", /* 80 */
93  "has_ready_scroll", NULL, NULL,
94  NULL, "make_invisible", "inv_locked", "is_wooded",
95  "is_hilly", "has_ready_skill", "has_ready_weapon", /* 90 */
96  "no_skill_ident", "is_blind", "can_see_in_dark", "is_cauldron",
97  "is_dust", "no_steal", "one_hit", NULL, "berserk", "neutral", /* 100 */
98  "no_attack", "no_damage", NULL, NULL, "activate_on_push",
99  "activate_on_release", "is_water", "use_content_on_gen", NULL, "is_buildable", /* 110 */
100  NULL, "blessed", "known_blessed"
101 };
102 
113 static char *cat_template(char *source, char *add) {
114  if (!source)
115  return add;
116  source = realloc(source, strlen(source)+strlen(add)+1);
117  strcat(source, add);
118  free(add);
119  return source;
120 }
121 
132 static int read_template(const char *name, char **buffer) {
133  FILE *file;
134  size_t size;
135  struct stat info;
136 
137  if (stat(name, &info)) {
138  printf("Couldn't stat template %s!\n", name);
139  return 1;
140  }
141 
142  (*buffer) = calloc(1, info.st_size+1);
143  if (!(*buffer)) {
144  printf("Template %s calloc failed!\n", name);
145  return 1;
146  }
147 
148  if (info.st_size == 0) {
149  (*buffer)[0] = '\0';
150  return 0;
151  }
152 
153  file = fopen(name, "rb");
154  if (!file) {
155  printf("Couldn't open template %s!\n", name);
156  free(*buffer);
157  return 1;
158  }
159  if (fread(*buffer, info.st_size, 1, file) != 1) {
160  printf("Couldn't read template %s!\n", name);
161  free(*buffer);
162  fclose(file);
163  return 1;
164  }
165  fclose(file);
166  return 0;
167 }
168 
186 static char *do_template(const char *template, const char **vars, const char **values) {
187  int count = 0;
188  const char *sharp = template;
189  int maxlen = 0;
190  int var = 0;
191  char *result;
192  char *current_result;
193  const char *end;
194 
195  while ((sharp = strchr(sharp, '#')) != NULL) {
196  sharp++;
197  count++;
198  }
199  if (!count)
200  return strdup(template);
201  if (count%2) {
202  printf("Malformed template, mismatched #!\n");
203  return strdup(template);
204  }
205 
206  while (vars[var] != NULL) {
207  if (strlen(values[var]) > maxlen)
208  maxlen = strlen(values[var]);
209  var++;
210  }
211  result = calloc(1, strlen(template)+maxlen*(count/2)+1);
212  if (!result)
213  return NULL;
214  current_result = result;
215 
216  sharp = template;
217  while ((sharp = strchr(sharp, '#')) != NULL) {
218  end = strchr(sharp+1, '#');
219  strncpy(current_result, template, sharp-template);
220  if (end == sharp+1) {
221  strcat(current_result, "#");
222  } else {
223  current_result = current_result+strlen(current_result);
224  var = 0;
225  while (vars[var] != 0 && strncmp(vars[var], sharp+1, end-sharp-1))
226  var++;
227  if (vars[var] == 0)
228  printf("Wrong tag: %s\n", sharp);
229  else
230  strcpy(current_result, values[var]);
231  }
232  current_result = current_result+strlen(current_result);
233  sharp = end+1;
234  template = sharp;
235  }
236  strcat(current_result, template);
237  return result;
238 }
239 
240 /**** Mhoram's code starts here *****/
241 
254 static void free_if_used(char *p) {
255  if (p && strlen(p) > 0) {
256  free(p);
257  }
258 }
259 
272 static int sortbyname(const void *a, const void *b) {
273  return (strcasecmp(*(const char **)a, *(const char **)b));
274 }
275 
289 static int sort_archetypes(const void *a, const void *b) {
290  archetype *aa;
291  archetype *bb;
292 
293  aa = *(archetype **)a;
294  bb = *(archetype **)b;
295 
296  return (strcasecmp(aa->clone.name, bb->clone.name));
297 }
298 
311 void push(String_Array *array, const char *string) {
312  int16_t i = array->count;
313 
314  array->item[i] = strdup_local(string);
315  array->count++;
316 }
317 
326 void free_data(String_Array *array) {
327  int item;
328 
329  for (item = 0; item < array->count; item++)
330  free(array->item[item]);
331  free(array->item);
332  array->item = NULL;
333 }
334 
345 const char *join_with_comma(String_Array *array) {
346  char *newtext;
347  int i;
348 
349  newtext = calloc(1, 1);
350  qsort(array->item, array->count, sizeof(char *), sortbyname);
351  for (i = 0; i < array->count; i++) {
352  if (i) {
353  newtext = realloc(newtext, strlen(newtext)+strlen(", ")+1);
354  newtext = strncat(newtext, ", ", 2);
355  }
356  newtext = realloc(newtext, strlen(newtext)+strlen(array->item[i])+1);
357  newtext = strncat(newtext, array->item[i], strlen(array->item[i]));
358  }
359  return newtext;
360 }
361 
362 int main(int argc, char *argv[]) {
363 
364  archetype *at;
365  int archnum = 0;
366  archetype *monster[4000];
367  int i;
368  char letter;
369  char last_letter;
370  char *wiki_page = NULL;
371  char *monster_entries = NULL;
372 
373  FILE *fp = NULL;
374  FILE *image_list;
375  char image_list_path[128];
376  char wikifile[128];
377  char *template;
378 
379  const char *wikidir = "/tmp"; /* Should change this to come from command line? */
380 
381  init_globals();
382  init_library();
383  init_readable();
384 
385  init_gods();
386 
387  /* Initialize templates */
388  if (read_template("templates/wiki/monster_page_head", &monster_page_head))
389  return;
390  if (read_template("templates/wiki/monster_page_foot", &monster_page_foot))
391  return;
392  if (read_template("templates/wiki/monster_entry", &monster_entry))
393  return;
394  if (read_template("templates/wiki/monster_canuse_row", &monster_canuse_row))
395  return;
396  if (read_template("templates/wiki/monster_protected_row", &monster_protected_row))
397  return;
398  if (read_template("templates/wiki/monster_vulnerable_row", &monster_vulnerable_row))
399  return;
400  if (read_template("templates/wiki/monster_special_row", &monster_special_row))
401  return;
402  if (read_template("templates/wiki/monster_attack_row", &monster_attack_row))
403  return;
404  if (read_template("templates/wiki/monster_lore_row", &monster_lore_row))
405  return;
406  sprintf(image_list_path, "%s/image_list", wikidir);
407  image_list = fopen(image_list_path, "w");
408  if (!image_list) {
409  LOG(llevError, "Unable to open image list file!\n");
410  exit(1);
411  }
412 
413  /* Pick out the monster archetypes and sort them into an array */
414  for (at = get_next_archetype(NULL); at != NULL; at = get_next_archetype(at)) {
415  if (QUERY_FLAG(&at->clone, FLAG_MONSTER)
416  && QUERY_FLAG(&at->clone, FLAG_ALIVE)) {
417  monster[archnum++] = at;
418  }
419  }
420  printf("Sorting...");
421  /* Calling qsort on monster, which is archetype** */
422  qsort(&monster[0], archnum, sizeof(archetype *), sort_archetypes);
423  printf("done. %i items found\n", archnum);
424 
425  last_letter = '\0';
426 
427  for (i = 0; i < archnum; i++) {
428  at = monster[i];
429  if (at) {
430  const char *key[16] = { NULL, };
431  const char *val[16] = { NULL, };
432  char buf[16][MAX_BUF];
433  int keycount = 0;
434  int res;
435 
436  letter = tolower(at->clone.name[0]);
437 
438  LOG(llevInfo, "Doing archetype %s\n", at->name);
439 
440  if (letter != last_letter) { /* New letter, new file */
441  if (fp) {
442  keycount = 0;
443  key[keycount] = NULL;
444  template = do_template(monster_page_foot, key, val);
445  res = fprintf(fp, "%s", template);
446  free(template);
447  template = NULL;
448  if (res < 0) {
449  LOG(llevError, "Unable to write to file!\n");
450  }
451  fclose(fp);
452  }
453 
454  snprintf(wikifile, sizeof(wikifile), "%s/%c", wikidir, letter);
455  fp = fopen(wikifile, "w");
456  if (!fp) {
457  fprintf(stderr, "Unable to write to wiki file!\n");
458  exit(1);
459  }
460 
461  char letterindex[256] = "";
462  char letterindexnext[7];
463  char li;
464  letterindexnext[0] = '\0';
465  for (li = 'a'; li <= 'z'; li++) {
466  char *p;
467 
468  if (li == letter) {
469  sprintf(letterindexnext, "%c ", toupper(li));
470  } else {
471  sprintf(letterindexnext, "[[%c]] ", toupper(li));
472  }
473  p = strchr(letterindex, '\0');
474  snprintf(p, letterindex+sizeof(letterindex)-p, "%s", letterindexnext);
475  }
476 
477  keycount = 0;
478  key[keycount] = "LETTER";
479  sprintf(buf[keycount], "%c", toupper(letter));
480  val[keycount++] = buf[keycount];
481  key[keycount] = "LETTERINDEX";
482  val[keycount++] = letterindex;
483  key[keycount] = NULL;
484  template = do_template(monster_page_head, key, val);
485  res = fprintf(fp, template);
486  free(template);
487  if (res < 0) {
488  LOG(llevError, "Unable to write to file!");
489  }
490  last_letter = letter;
491  }
492 
493  /* add a monster entry */
494  char *canuse_row;
495  char *protected_row;
496  char *vulnerable_row;
497  char *special_row;
498  char *attack_row;
499  char *lore_row;
500  const int CANUSE_LENGTH = 16;
501  String_Array canuse;
502  String_Array resist;
503  String_Array vulner;
504  String_Array attack;
505  String_Array special;
506  /* Some flags that seemed useful; may need to add to this list.
507  * *special_names[] is used because some of the names in
508  * define.h are a bit awkward. Last one is negative to mark end.
509  */
510  const int8_t special_flags[] = { 21, 93, 52, 38, 13, 32, 61, -1 };
511  const char *special_names[] = {
512  "see invisible",
513  "see in dark",
514  "spellcaster",
515  "unaggressive",
516  "flying",
517  "splitting",
518  "x-ray vision"
519  };
520  int j;
521 
522  canuse.item = calloc((CANUSE_LENGTH+1), sizeof(const char *));
523  resist.item = calloc((NROFATTACKS+1), sizeof(const char *));
524  vulner.item = calloc((NROFATTACKS+1), sizeof(const char *));
525  attack.item = calloc((NROFATTACKS+1), sizeof(const char *));
526  special.item = calloc((NROFATTACKS+1), sizeof(const char *));
527 
528  /* Do lore row */
529  if (at->clone.lore) {
530  key[keycount] = "LORE";
531  key[keycount+1] = NULL;
532  val[keycount] = at->clone.lore;
533  keycount++;
534  lore_row = do_template(monster_lore_row, key, val);
535  } else
536  lore_row = strdup("");
537 
538  /* Do canuse row */
539  canuse.count = 0;
540  keycount = 0;
541  for (j = 1; j <= NUM_FLAGS; j++) {
542  if (QUERY_FLAG(&at->clone, j)
543  && flag_names[j]
544  && !strncmp(flag_names[j], "can_use_", 8)) {
545  push(&canuse, flag_names[j]+8);
546  }
547  }
548  if (canuse.count) {
549  key[keycount] = "CANUSE";
550  key[keycount+1] = NULL;
551  val[keycount] = join_with_comma(&canuse);
552  canuse_row = do_template(monster_canuse_row, key, val);
553  free(val[keycount]);
554  } else
555  canuse_row = strdup("");
556 
557  /* Do protected/vulnerable rows */
558  resist.count = 0;
559  vulner.count = 0;
560  for (j = 0; j <= NROFATTACKS; j++) {
561  if (at->clone.resist[j] && attacktype_desc[j]) {
562  char rowtext[32];
563 
564  if (at->clone.resist[j] < 0) {
565  sprintf(rowtext, "%s %i", attacktype_desc[j], at->clone.resist[j]);
566  push(&vulner, rowtext);
567  } else {
568  sprintf(rowtext, "%s +%i", attacktype_desc[j], at->clone.resist[j]);
569  push(&resist, rowtext);
570  }
571  }
572  }
573  keycount = 0;
574  if (resist.count) {
575  key[keycount] = "PROTECTED";
576  key[keycount+1] = NULL;
577  val[keycount] = join_with_comma(&resist);
578  protected_row = do_template(monster_protected_row, key, val);
579  free(val[keycount]);
580  } else
581  protected_row = strdup("");
582 
583  keycount = 0;
584  if (vulner.count) {
585  key[keycount] = "VULNERABLE";
586  key[keycount+1] = NULL;
587  val[keycount] = join_with_comma(&vulner);
588  vulnerable_row = do_template(monster_vulnerable_row, key, val);
589  free(val[keycount]);
590  } else
591  vulnerable_row = strdup("");
592 
593  /* Do attacktype row */
594  attack.count = 0;
595  keycount = 0;
596  val[keycount] = NULL;
597  for (j = 0; j <= NROFATTACKS; j++) {
598  if (at->clone.attacktype&(1U<<j)) {
599  push(&attack, attacktype_desc[j]);
600  }
601  }
602  if (attack.count) {
603  key[keycount] = "ATTACKS";
604  key[keycount+1] = NULL;
605  val[keycount] = join_with_comma(&attack);
606  attack_row = do_template(monster_attack_row, key, val);
607  free(val[keycount]);
608  } else
609  attack_row = strdup("");
610 
611  /* Do special row */
612  special.count = 0;
613  keycount = 0;
614  val[keycount] = NULL;
615  for (j = 0; special_flags[j] >= 0; j++) {
616  if (QUERY_FLAG(&at->clone, special_flags[j])) {
617  push(&special, special_names[j]);
618  }
619  }
620  if (special.count) {
621  key[keycount] = "SPECIAL";
622  key[keycount+1] = NULL;
623  val[keycount] = join_with_comma(&special);
624  special_row = do_template(monster_special_row, key, val);
625  free(val[keycount]);
626  } else
627  special_row = strdup("");
628 
629  keycount = 0;
630  key[keycount] = "CANUSEROW";
631  val[keycount++] = canuse_row;
632  key[keycount] = "PROTECTEDROW";
633  val[keycount++] = protected_row;
634  key[keycount] = "VULNERABLEROW";
635  val[keycount++] = vulnerable_row;
636  key[keycount] = "SPECIALROW";
637  val[keycount++] = attack_row;
638  key[keycount] = "ATTACKROW";
639  val[keycount++] = special_row;
640  key[keycount] = "LOREROW";
641  val[keycount++] = lore_row;
642  key[keycount] = "XP";
643  sprintf(buf[keycount], "%li", at->clone.stats.exp);
644  val[keycount++] = buf[keycount];
645  key[keycount] = "HP";
646  sprintf(buf[keycount], "%i", at->clone.stats.hp);
647  val[keycount++] = buf[keycount];
648  key[keycount] = "AC";
649  sprintf(buf[keycount], "%i", at->clone.stats.ac);
650  val[keycount++] = buf[keycount];
651  key[keycount] = "NAME";
652  val[keycount++] = at->clone.name;
653  key[keycount] = "RACE";
654  if (at->clone.race) {
655  val[keycount++] = at->clone.race;
656  } else {
657  val[keycount++] = NA;
658  }
659  if (at->clone.face->name) {
660  key[keycount] = "FACE";
661  sprintf(buf[keycount], "{{http://aaron.baugher.biz/images/cf/%s.png}}", at->clone.face->name);
662  val[keycount++] = buf[keycount];
663  sprintf(buf[keycount], "%s.png\n", at->clone.face->name);
664  fprintf(image_list, buf[keycount]);
665  }
666 /* Plan to add generator face too, when I decide how */
667  key[keycount] = "GENFACE";
668  val[keycount++] = "";
669  key[keycount] = NULL;
670 
671  template = do_template(monster_entry, key, val);
672  fprintf(fp, template);
673  free(template);
674  template = NULL;
675 
676  free_data(&canuse);
677  free_data(&resist);
678  free_data(&vulner);
679  free_data(&attack);
680  free_data(&special);
681  free(canuse_row);
682  free(protected_row);
683  free(vulnerable_row);
684  free(attack_row);
685  free(special_row);
686  free(lore_row);
687  } else {
688  LOG(llevError, "Something is very wrong.\n");
689  }
690  }
691  fclose(image_list);
692 }
693 
694 void set_map_timeout(void) {
695  /* doesn't need to do anything */
696 }
697 
698 #include <global.h>
699 
700 /* some plagarized code from apply.c--I needed just these two functions
701  without all the rest of the junk, so.... */
702 int apply_auto(object *op) {
703  object *tmp = NULL;
704  int i;
705 
706  switch (op->type) {
707  case SHOP_FLOOR:
708  if (!HAS_RANDOM_ITEMS(op))
709  return 0;
710  do {
711  i = 10; /* let's give it 10 tries */
712  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? op->stats.exp : 5)) == NULL && --i)
713  ;
714  if (tmp == NULL)
715  return 0;
718  tmp = NULL;
719  }
720  } while (!tmp);
721 
723  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
725  tmp = identify(tmp);
726  break;
727 
728  case TREASURE:
729  if (HAS_RANDOM_ITEMS(op))
730  while ((op->stats.hp--) > 0)
731  create_treasure(op->randomitems, op, GT_ENVIRONMENT, op->stats.exp ? op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
732  object_remove(op);
734  break;
735  }
736 
737  return tmp ? 1 : 0;
738 }
739 
740 /* apply_auto_fix goes through the entire map (only the first time
741  * when an original map is loaded) and performs special actions for
742  * certain objects (most initialization of chests and creation of
743  * treasures and stuff). Calls apply_auto if appropriate.
744  */
746  object *tmp, *above = NULL;
747  int x, y;
748 
749  for (x = 0; x < MAP_WIDTH(m); x++)
750  for (y = 0; y < MAP_HEIGHT(m); y++)
751  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = above) {
752  above = tmp->above;
753 
755  apply_auto(tmp);
756  else if (tmp->type == TREASURE) {
757  if (HAS_RANDOM_ITEMS(tmp))
758  while ((tmp->stats.hp--) > 0)
759  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
760  }
761  if (tmp
762  && tmp->arch
763  && tmp->type != PLAYER
764  && tmp->type != TREASURE
765  && tmp->randomitems) {
766  if (tmp->type == CONTAINER) {
767  if (HAS_RANDOM_ITEMS(tmp))
768  while ((tmp->stats.hp--) > 0)
769  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
770  } else if (HAS_RANDOM_ITEMS(tmp)) {
771  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
772  if (QUERY_FLAG(tmp, FLAG_MONSTER)) {
774  }
775  }
776  }
777  }
778  for (x = 0; x < MAP_WIDTH(m); x++)
779  for (y = 0; y < MAP_HEIGHT(m); y++)
780  for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = tmp->above)
781  if (tmp->above
782  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
783  check_trigger(tmp, tmp->above);
784 }
785 
786 #ifndef DOXYGEN_SHOULD_SKIP_THIS
787 
793 void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *txt) {
794  fprintf(logfile, "%s\n", txt);
795 }
796 
797 void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format, ...) {
798  va_list ap;
799  va_start(ap, format);
800  vfprintf(logfile, format, ap);
801  va_end(ap);
802 }
803 
804 void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1) {
805  fprintf(logfile, "ext_info_map: %s\n", str1);
806 }
807 
808 void move_firewall(object *ob) {
809 }
810 
811 void emergency_save(int x) {
812 }
813 
814 void clean_tmp_files(void) {
815 }
816 
817 void esrv_send_item(object *ob, object *obx) {
818 }
819 
820 void dragon_ability_gain(object *ob, int x, int y) {
821 }
822 
824 }
825 
826 object *find_skill_by_number(object *who, int skillno) {
827  return NULL;
828 }
829 
830 void esrv_del_item(player *pl, object *ob) {
831 }
832 
834 }
835 
836 #endif /* dummy DOXYGEN_SHOULD_SKIP_THIS */
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:171
init_globals
void init_globals(void)
Definition: init.cpp:395
living::exp
int64_t exp
Definition: living.h:47
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:184
esrv_update_spells
void esrv_update_spells(player *pl)
Definition: bwp.c:833
PLAYER
@ PLAYER
Definition: object.h:112
dragon_ability_gain
void dragon_ability_gain(object *ob, int x, int y)
Definition: bwp.c:820
sort_archetypes
static int sort_archetypes(const void *a, const void *b)
Definition: bwp.c:289
global.h
llevError
@ llevError
Definition: logger.h:11
main
int main(int argc, char *argv[])
Definition: bwp.c:362
string_array::count
int16_t count
Definition: bwp.c:57
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
monster_page_foot
char * monster_page_foot
Definition: bwp.c:47
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
player
Definition: player.h:105
strdup_local
#define strdup_local
Definition: compat.h:29
diamondslots.x
x
Definition: diamondslots.py:15
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
get_next_archetype
archetype * get_next_archetype(archetype *current)
Definition: assets.cpp:262
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:139
flag_names
const char *const flag_names[NUM_FLAGS+1]
Definition: bwp.c:70
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *txt)
Definition: bwp.c:793
do_template
static char * do_template(const char *template, const char **vars, const char **values)
Definition: bwp.c:186
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:188
set_darkness_map
void set_darkness_map(mapstruct *m)
Definition: bwp.c:823
monster_vulnerable_row
char * monster_vulnerable_row
Definition: bwp.c:51
guildjoin.ob
ob
Definition: guildjoin.py:42
NUM_FLAGS
#define NUM_FLAGS
Definition: define.h:374
mad_mage_user.file
file
Definition: mad_mage_user.py:15
TREASURE
@ TREASURE
Definition: object.h:115
flags
static const flag_definition flags[]
Definition: gridarta-types-convert.cpp:101
Ice.tmp
int tmp
Definition: Ice.py:207
tolower
#define tolower(C)
Definition: c_new.cpp:30
free_data
void free_data(String_Array *array)
Definition: bwp.c:326
monster
the faster the spell may be cast there are several other common only the caster may be affected by the spell The most common spell range is that of touch This denotes that the caster much touch the recipient of the spell in order to release the spell monster
Definition: spell-info.txt:45
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
monster_protected_row
char * monster_protected_row
Definition: bwp.c:50
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:137
source
Almost all the spell_ *base png files are taken from JXClient s source
Definition: readme-icons.txt:1
smoking_pipe.color
color
Definition: smoking_pipe.py:5
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.cpp:263
buf
StringBuffer * buf
Definition: readable.cpp:1552
object::resist
int16_t resist[NROFATTACKS]
Definition: object.h:351
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
free_if_used
static void free_if_used(char *p)
Definition: bwp.c:254
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
clean_tmp_files
void clean_tmp_files(void)
Definition: bwp.c:814
init_gods
void init_gods(void)
Definition: holy.cpp:59
m
static event_registration m
Definition: citylife.cpp:425
join_with_comma
const char * join_with_comma(String_Array *array)
Definition: bwp.c:345
autojail.who
who
Definition: autojail.py:3
letter
**Media tags please refer to the protocol file in doc Developers protocol Quick for your pleasure an example[/b][i] This is an old letter
Definition: media-tags.txt:15
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1555
disinfect.map
map
Definition: disinfect.py:4
monster_special_row
char * monster_special_row
Definition: bwp.c:52
rotate-tower.result
bool result
Definition: rotate-tower.py:13
String_Array
struct string_array String_Array
push
void push(String_Array *array, const char *string)
Definition: bwp.c:311
archetype::clone
object clone
Definition: object.h:478
Face::name
sstring name
Definition: face.h:19
string_array
Definition: bwp.c:56
CONTAINER
@ CONTAINER
Definition: object.h:236
init_readable
void init_readable(void)
Definition: readable.cpp:895
esrv_send_item
void esrv_send_item(object *ob, object *obx)
Definition: bwp.c:817
object::face
const Face * face
Definition: object.h:341
Ice.b
b
Definition: Ice.py:48
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
monster_lore_row
char * monster_lore_row
Definition: bwp.c:54
monster_canuse_row
char * monster_canuse_row
Definition: bwp.c:49
disinfect.count
int count
Definition: disinfect.py:7
archetype
Definition: object.h:474
logfile
FILE * logfile
Definition: init.cpp:114
GT_ENVIRONMENT
@ GT_ENVIRONMENT
Definition: treasure.h:31
object::race
sstring race
Definition: object.h:326
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: bwp.c:797
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.cpp:2095
monster_page_head
char * monster_page_head
Definition: bwp.c:46
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:74
move_firewall
void move_firewall(object *ob)
Definition: bwp.c:808
MAX_BUF
#define MAX_BUF
Definition: define.h:35
monster_check_apply_all
void monster_check_apply_all(object *monster)
Definition: monster.cpp:2001
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Definition: bwp.c:745
find_skill_by_number
object * find_skill_by_number(object *who, int skillno)
Definition: bwp.c:826
above
Magical Runes Runes are magical inscriptions on the dungeon which cast a spell or detonate when something steps on them Flying objects don t detonate runes Beware ! Runes are invisible most of the time They are only visible occasionally ! There are several runes which are there are some special runes which may only be called with the invoke and people may apply it to read it Maybe useful for mazes ! This rune will not nor is it ordinarily invisible Partial Visibility of they ll be visible only part of the time They have so the higher your the better hidden the runes you make are Examples of whichever way you re facing invoke magic rune transfer as above
Definition: runes-guide.txt:50
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.cpp:518
object::lore
sstring lore
Definition: object.h:332
llevInfo
@ llevInfo
Definition: logger.h:12
esrv_del_item
void esrv_del_item(player *pl, object *ob)
Definition: bwp.c:830
init_library
void init_library(void)
Definition: init.cpp:323
object::name
sstring name
Definition: object.h:319
attacktype_desc
const char *const attacktype_desc[NROFATTACKS]
Definition: init.cpp:40
item
Definition: item.py:1
emergency_save
void emergency_save(int x)
Definition: bwp.c:811
mapstruct
Definition: map.h:314
give.op
op
Definition: give.py:33
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Definition: define.h:250
apply_auto
int apply_auto(object *op)
Definition: bwp.c:702
format
Python Guilds Quick outline Add a guild(mapmakers) this is still a problem *after dropping the token to gain access to the stove a woodfloor now appears which is Toolshed Token(found in Guild_HQ) *Note also have multiple gates in place to protect players and items from the mana explosion drop x for Jewelers room *Jewelers room works just need to determine what x is drop x for Thaumaturgy room *Thaumaturgy room works just need to determine what x is drop gold dropping the Firestar named fearless allows access to but I suspect that the drop location of the chest is not as intended because the player is in the way once you enter the chest the exit back to the basement is things such as the message et al reside on teleporters which then transport items to the map as they are when the map is already purchased items reappear in that area From my this does not cause any problems at the moment But this should be corrected fixed Major it s now possible to buy guilds Ryo Update Uploaded guild package to CVS Changes the cauldrons and the charging room I spent a while agonizing over They were natural guild enhancements but much too much value for any reasonable expense to buy them Then I thought that they should be pay access but at a greatly reduced rate SO when you buy a forge or whatever for your guild it is available on a perplayer daily rate but it will be accessable for testing and to DMs to play with Like I said lots still to do with the especially comingt up with quest items for buying things like the new workshops and stuff One of the things I would like some input on would be proposals for additional fields for either the guildhouses or guild datafiles to play with Currently the Guildhouse but there is no reason we can t have more than one measure of a guild perhaps have dues relate to Dues and use points for some other suspended or inactive or when a guild is founded inactive active Guilds have the format
Definition: README.txt:140
exit
Install Bug reporting Credits but rather whatever guild name you are using *With the current map and server there are three they and GreenGoblin *Whatever name you give the folder should but it will still use GUILD_TEMPLATE *You can change what guild it uses by editing the map files Modify Map or objects if you want to use the optional Python based Guild Storage hall The first three are on the main the next two are in the guild_hq and the final one is in hallofjoining Withe the Storage three objects are found on the main floor and the last two are in the basement It s not that but you will need a map editor You find the object that has the click edit and change the line script options(which currently is "GUILD_TEMPALTE") to the guild you wish to use. And make sure you use the same one for all of them or it won 't work. Here 's a quick HOWTO for using the map editor to make these changes edit the mainfloor map exit(x15, y29 - set to/Edit/This/Exit/Path in the template) back to the world map as well. If you are using the Storage Hall map(storage_hall)
NA
#define NA
Definition: bwp.c:38
diamondslots.y
y
Definition: diamondslots.py:16
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:76
living::ac
int8_t ac
Definition: living.h:38
read_template
static int read_template(const char *name, char **buffer)
Definition: bwp.c:132
strcasecmp
int strcasecmp(const char *s1, const char *s2)
castle_read.key
key
Definition: castle_read.py:64
set_map_timeout
void set_map_timeout(void)
Definition: bwp.c:694
monster_attack_row
char * monster_attack_row
Definition: bwp.c:53
object_remove
void object_remove(object *op)
Definition: object.cpp:1828
a
Magical Runes Runes are magical inscriptions on the dungeon which cast a spell or detonate when something steps on them Flying objects don t detonate runes Beware ! Runes are invisible most of the time They are only visible occasionally ! There are several runes which are there are some special runes which may only be called with the invoke and people may apply it to read it Maybe useful for mazes ! This rune will not nor is it ordinarily invisible Partial Visibility of they ll be visible only part of the time They have a(your level/2) chance of being visible in any given round
FLAG_UNPAID
#define FLAG_UNPAID
Definition: define.h:236
sortbyname
static int sortbyname(const void *a, const void *b)
Definition: bwp.c:272
cat_template
static char * cat_template(char *source, char *add)
Definition: bwp.c:113
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.cpp:295
archetype::name
sstring name
Definition: object.h:475
say.item
dictionary item
Definition: say.py:149
object::stats
living stats
Definition: object.h:378
object::attacktype
uint32_t attacktype
Definition: object.h:352
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
string_array::item
char ** item
Definition: bwp.c:58
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
ext_info_map
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Definition: bwp.c:804
living::hp
int16_t hp
Definition: living.h:40
altar_valkyrie.res
int res
Definition: altar_valkyrie.py:74
monster_entry
char * monster_entry
Definition: bwp.c:48
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
identify
object * identify(object *op)
Definition: item.cpp:1425