Crossfire Server, Trunk  R21189
arch.c
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 
28 #include "global.h"
29 
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "loader.h"
35 
36 static void add_arch(archetype *at);
37 
39 static int arch_cmp = 0;
40 static int arch_search = 0;
41 int arch_init;
43 static void load_archetypes(void);
44 
58  archetype *at;
59  const char *tmp;
60 
61  if (name == NULL)
62  return (archetype *)NULL;
63  tmp = add_string(name);
64  for (at = first_archetype; at != NULL; at = at->next) {
65  if (at->clone.name == tmp) {
66  free_string(tmp);
67  return at;
68  }
69  }
70  free_string(tmp);
71  return NULL;
72 }
73 
83 archetype *find_archetype_by_object_type_name(int type, const char *name) {
84  archetype *at;
85 
86  if (name == NULL)
87  return NULL;
88 
89  for (at = first_archetype; at != NULL; at = at->next) {
90  if (at->clone.type == type && strcmp(at->clone.name, name) == 0)
91  return at;
92  }
93 
94  return NULL;
95 }
96 
107 archetype *get_archetype_by_skill_name(const char *skill, int type) {
108  archetype *at;
109 
110  if (skill == NULL)
111  return NULL;
112 
113  for (at = first_archetype; at != NULL; at = at->next) {
114  if (((type == -1) || (type == at->clone.type))
115  && (at->clone.skill) && (!strcmp(at->clone.skill, skill)))
116  return at;
117  }
118  return NULL;
119 }
120 
136 archetype *get_archetype_by_type_subtype(int type, int subtype) {
137  archetype *at;
138 
139  for (at = first_archetype; at != NULL; at = at->next) {
140  if (((type == -1) || (type == at->clone.type))
141  && (subtype == -1 || subtype == at->clone.subtype))
142  return at;
143  }
144  return NULL;
145 }
146 
160 object *create_archetype_by_object_name(const char *name) {
161  archetype *at;
162  char tmpname[MAX_BUF];
163  size_t i;
164 
165  strncpy(tmpname, name, MAX_BUF-1);
166  tmpname[MAX_BUF-1] = 0;
167  for (i = strlen(tmpname); i > 0; i--) {
168  tmpname[i] = 0;
169  at = find_archetype_by_object_name(tmpname);
170  if (at != NULL) {
171  return arch_to_object(at);
172  }
173  }
174  return create_singularity(name);
175 }
176 
182 void init_archetypes(void) {
183  if (first_archetype != NULL) /* Only do this once */
184  return;
185  arch_init = 1;
186  load_archetypes();
187  arch_init = 0;
188  empty_archetype = find_archetype("empty_archetype");
189  if (empty_archetype == NULL)
191  /* init_blocksview();*/
192 }
193 
198 void arch_info(object *op) {
200  "%d searches and %d strcmp()'s",
202 }
203 
207 void clear_archetable(void) {
208  memset((void *)arch_table, 0, ARCHTABLE*sizeof(archetype *));
209 }
210 
214 static void init_archetable(void) {
215  archetype *at;
216 
217  LOG(llevDebug, "arch: setting up archetable\n");
218  for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) {
219  if (at->name == NULL) {
220  LOG(llevError, "archetype without name? %s\n", at->clone.name ? at->clone.name : "(no clone name)");
221  abort();
222  }
223  add_arch(at);
224  }
225 }
226 
236  object_dump(&at->clone, sb);
237 }
238 
245  archetype *at;
246 
247  for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) {
248  StringBuffer *sb;
249  char *diff;
250 
251  sb = stringbuffer_new();
252  dump_arch(at, sb);
253  diff = stringbuffer_finish(sb);
254  LOG(llevDebug, "%s\n", diff);
255  free(diff);
256  }
257 }
258 
265 void free_arch(archetype *at) {
266  if (at->name)
267  free_string(at->name);
268  if (at->clone.name)
269  free_string(at->clone.name);
270  if (at->clone.name_pl)
272  if (at->clone.title)
273  free_string(at->clone.title);
274  if (at->clone.race)
275  free_string(at->clone.race);
276  if (at->clone.slaying)
278  if (at->clone.msg)
279  free_string(at->clone.msg);
280  free(at->clone.discrete_damage);
282  free(at);
283 }
284 
289 void free_all_archs(void) {
290  archetype *at, *next;
291  int i = 0;
292 
293  for (at = first_archetype; at != NULL; at = next) {
294  if (at->more)
295  next = at->more;
296  else
297  next = at->next;
298  free_arch(at);
299  i++;
300  }
301  first_archetype = NULL;
302  /* Reset the hashtable */
304  LOG(llevDebug, "Freed %d archetypes\n", i);
305 }
306 
315  archetype *new;
316 
317  new = (archetype *)CALLOC(1, sizeof(archetype));
318  if (new == NULL)
320  new->next = NULL;
321  new->name = NULL;
322  new->clone.other_arch = NULL;
323  new->clone.name = NULL;
324  new->clone.name_pl = NULL;
325  new->clone.title = NULL;
326  new->clone.race = NULL;
327  new->clone.slaying = NULL;
328  new->clone.msg = NULL;
329  object_clear(&new->clone); /* to initial state other also */
330  CLEAR_FLAG((&new->clone), FLAG_FREED); /* This shouldn't matter, since object_copy() */
331  SET_FLAG((&new->clone), FLAG_REMOVED); /* doesn't copy these flags... */
332  new->head = NULL;
333  new->more = NULL;
334  new->clone.arch = new;
335  return new;
336 }
337 
348 static void first_arch_pass(FILE *fp) {
349  archetype *at, *head = NULL, *last_more = NULL;
350  int i, first = LO_NEWFILE;
351 
352  at = get_archetype_struct();
353  first_archetype = at;
354 
355  while ((i = load_object(fp, &at->clone, first, 0))) {
356  first = 0;
357  at->clone.speed_left = (float)(-0.1);
358 
359  switch (i) {
360  case LL_NORMAL: /* A new archetype, just link it with the previous */
361  if (last_more != NULL)
362  last_more->next = at;
363  if (head != NULL)
364  head->next = at;
365  head = last_more = at;
366  at->tail_x = 0;
367  at->tail_y = 0;
368  break;
369 
370  case LL_MORE: /* Another part of the previous archetype, link it correctly */
371  at->head = head;
372  at->clone.head = &head->clone;
373  if (last_more != NULL) {
374  last_more->more = at;
375  last_more->clone.more = &at->clone;
376  }
377  last_more = at;
378 
379  /* Set FLAG_MONSTER throughout parts if head has it */
380  if (QUERY_FLAG(&head->clone, FLAG_MONSTER)) {
381  SET_FLAG(&at->clone, FLAG_MONSTER);
382  }
383 
384  /* If this multipart image is still composed of individual small
385  * images, don't set the tail_.. values. We can't use them anyways,
386  * and setting these to zero makes the map sending to the client much
387  * easier as just looking at the head, we know what to do.
388  */
389  if (at->clone.face != head->clone.face) {
390  head->tail_x = 0;
391  head->tail_y = 0;
392  } else {
393  if (at->clone.x > head->tail_x)
394  head->tail_x = at->clone.x;
395  if (at->clone.y > head->tail_y)
396  head->tail_y = at->clone.y;
397  }
398  break;
399  }
400 
401  at = get_archetype_struct();
402  }
403  at->clone.arch = NULL; /* arch is checked for temporary archetypes if not NULL. */
404  free(at);
405 }
406 
416 static void second_arch_pass(FILE *fp) {
417  char buf[MAX_BUF], *variable = buf, *argument, *cp;
418  archetype *at = NULL, *other;
419  object *inv;
420 
421  while (fgets(buf, MAX_BUF, fp) != NULL) {
422  if (*buf == '#')
423  continue;
424  if ((argument = strchr(buf, ' ')) != NULL) {
425  *argument = '\0', argument++;
426  cp = argument+strlen(argument)-1;
427  while (isspace(*cp)) {
428  *cp = '\0';
429  cp--;
430  }
431  }
432  if (!strcmp("Object", variable)) {
433  if ((at = find_archetype(argument)) == NULL)
434  {
435  LOG(llevError, "Fatal: failed to find arch %s in second_arch_pass\n", argument);
437  }
438  } else if (!strcmp("other_arch", variable)) {
439  if (at != NULL && at->clone.other_arch == NULL) {
440  if ((other = find_archetype(argument)) == NULL)
441  LOG(llevError, "Warning: failed to find other_arch %s\n", argument);
442  else if (at != NULL)
443  at->clone.other_arch = other;
444  }
445  } else if (!strcmp("randomitems", variable)) {
446  if (at != NULL) {
447  treasurelist *tl = find_treasurelist(argument);
448  if (tl == NULL)
449  LOG(llevError, "Failed to link treasure to arch (%s): %s\n", at->name, argument);
450  else
451  at->clone.randomitems = tl;
452  }
453  } else if (!strcmp("arch", variable)) {
454  inv = create_archetype(argument);
455  load_object(fp, inv, LO_LINEMODE, 0);
456  if (at) {
457  object_insert_in_ob(inv, &at->clone);
458  } else {
459  LOG(llevError, "Got an arch %s not inside an Object.\n", argument);
461  }
462  }
463  }
464 }
465 
469 void check_generators(void) {
470  const archetype *at;
471  int abort = 0;
472 
473  for (at = first_archetype; at != NULL; at = at->next) {
474  if (!QUERY_FLAG(&at->clone, FLAG_GENERATOR))
475  continue;
476 
477  if (!QUERY_FLAG(&at->clone, FLAG_CONTENT_ON_GEN) && at->clone.other_arch == NULL) {
478  LOG(llevError, "Fatal: %s is generator without content_on_gen but lacks other_arch.\n", at->name);
479  abort = 1;
480  continue;
481  }
482  if (QUERY_FLAG(&at->clone, FLAG_CONTENT_ON_GEN) && at->clone.inv == NULL) {
483  LOG(llevError, "Fatal: %s is generator with content_on_gen but lacks inventory.\n", at->name);
484  abort = 1;
485  continue;
486  }
487  }
488 
489  if (abort)
491 }
492 
497 void check_summoned(void) {
498  const archetype *at;
499 
500  for (at = first_archetype; at != NULL; at = at->next) {
501  if (at->clone.type == SPELL && at->clone.subtype == SP_SUMMON_GOLEM && at->clone.other_arch) {
502  if (at->clone.other_arch->clone.move_type == 0) {
503  LOG(llevError, "Summonable archetype %s [%s] has no move_type defined!\n", at->clone.other_arch->name, at->clone.other_arch->clone.name);
505  }
506  }
507  }
508 }
509 
513 static void check_spells(void) {
514  int abort = 0;
515  const archetype *at;
516 
517  for (at = first_archetype; at != NULL; at = at->next) {
518  if (at->clone.type == SPELL && at->clone.skill == NULL) {
519  LOG(llevError, "Spell archetype %s [%s] has no skill defined!\n", at->name, at->clone.name);
520  abort = 1;
521  }
522  }
523  if (abort)
525 }
526 
534 static void load_archetypes(void) {
535  FILE *fp;
536  char filename[MAX_BUF];
537 
538  snprintf(filename, sizeof(filename), "%s/%s", settings.datadir, settings.archetypes);
539  if ((fp = fopen(filename, "r")) == NULL) {
540  LOG(llevError, " Can't open archetype file.\n");
541  return;
542  }
544 
545  LOG(llevDebug, "arch: starting pass 1...\n");
546  first_arch_pass(fp);
547  init_archetable();
548  rewind(fp);
549 
550  LOG(llevDebug, "arch: loading treasures\n");
551  load_treasures();
552  LOG(llevDebug, "arch: starting pass 2...\n");
553  second_arch_pass(fp);
555  check_spells();
556  check_summoned();
557  fclose(fp);
558 }
559 
571 object *arch_to_object(archetype *at) {
572  object *op;
573 
574  if (at == NULL) {
575  LOG(llevError, "Couldn't find archetype.\n");
576  return NULL;
577  }
578  op = object_new();
579  object_copy_with_inv(&at->clone, op);
580  op->arch = at;
581  return op;
582 }
583 
597 object *create_singularity(const char *name) {
598  object *op;
599  char buf[MAX_BUF];
600 
601  snprintf(buf, sizeof(buf), "%s (%s)", ARCH_SINGULARITY, name);
602  op = object_new();
603  op->arch = empty_archetype;
604  op->name = add_string(buf);
605  op->name_pl = add_string(buf);
606  SET_FLAG(op, FLAG_NO_PICK);
607  return op;
608 }
609 
620 object *create_archetype(const char *name) {
621  archetype *at;
622 
623  at = find_archetype(name);
624  if (at == NULL)
625  return create_singularity(name);
626  return arch_to_object(at);
627 }
628 
638 static unsigned long
639 hasharch(const char *str, int tablesize) {
640  unsigned long hash = 0;
641  int i = 0;
642  const char *p;
643 
644  /* use the one-at-a-time hash function, which supposedly is
645  * better than the djb2-like one used by perl5.005, but
646  * certainly is better then the bug used here before.
647  * see http://burtleburtle.net/bob/hash/doobs.html
648  */
649  for (p = str; i < MAXSTRING && *p; p++, i++) {
650  hash += *p;
651  hash += hash<<10;
652  hash ^= hash>>6;
653  }
654  hash += hash<<3;
655  hash ^= hash>>11;
656  hash += hash<<15;
657  return hash%tablesize;
658 }
659 
666 archetype *try_find_archetype(const char *name) {
667  archetype *at;
668  unsigned long index;
669 
670  if (name == NULL)
671  return (archetype *)NULL;
672 
673  index = hasharch(name, ARCHTABLE);
674  arch_search++;
675  for (;;) {
676  at = arch_table[index];
677  if (at == NULL) {
678  return NULL;
679  }
680  arch_cmp++;
681  if (!strcmp(at->name, name))
682  return at;
683  if (++index >= ARCHTABLE)
684  index = 0;
685  }
686 }
687 
695 archetype *find_archetype(const char *name) {
696  archetype *at;
697 
698  if (name == NULL)
699  return (archetype *)NULL;
700  at = try_find_archetype(name);
701  if (at == NULL)
702  LOG(llevError, "Couldn't find archetype %s\n", name);
703  return at;
704 }
705 
710 static void add_arch(archetype *at) {
711  unsigned long index = hasharch(at->name, ARCHTABLE), org_index = index;
712 
713  for (;;) {
714  if (arch_table[index] == NULL) {
715  arch_table[index] = at;
716  return;
717  }
718  if (++index == ARCHTABLE)
719  index = 0;
720  if (index == org_index)
722  }
723 }
724 
737  object *op, *prev = NULL, *head = NULL;
738 
739  while (at) {
740  op = arch_to_object(at);
741  op->x = at->clone.x;
742  op->y = at->clone.y;
743  if (head)
744  op->head = head, prev->more = op;
745  if (!head)
746  head = op;
747  prev = op;
748  at = at->more;
749  }
750  return (head);
751 }
752 
753 /*** end of arch.c ***/
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:315
#define ARCH_SINGULARITY
Definition: object.h:574
archetype * find_archetype(const char *name)
Definition: arch.c:695
MoveType move_type
Definition: object.h:424
#define LO_LINEMODE
Definition: loader.h:16
int8_t tail_x
Definition: object.h:471
static void first_arch_pass(FILE *fp)
Definition: arch.c:348
const char * race
Definition: object.h:318
#define SET_FLAG(xyz, p)
Definition: define.h:223
static int arch_search
Definition: arch.c:40
static void check_spells(void)
Definition: arch.c:513
void object_copy_with_inv(const object *src_ob, object *dest_ob)
Definition: object.c:1006
object * create_singularity(const char *name)
Definition: arch.c:597
void fatal(enum fatal_error err)
Definition: utils.c:597
treasurelist * find_treasurelist(const char *name)
Definition: treasure.c:290
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
void free_string(sstring str)
Definition: shstr.c:280
struct treasureliststruct * randomitems
Definition: object.h:385
object clone
Definition: object.h:470
static archetype * arch_table[ARCHTABLE]
Definition: arch.c:38
const char * slaying
Definition: object.h:319
void init_archetypes(void)
Definition: arch.c:182
static void init_archetable(void)
Definition: arch.c:214
void check_summoned(void)
Definition: arch.c:497
static void add_arch(archetype *at)
Definition: arch.c:710
void dump_all_archetypes(void)
Definition: arch.c:244
uint8_t subtype
Definition: object.h:339
int arch_init
Definition: arch.c:41
object * create_archetype_by_object_name(const char *name)
Definition: arch.c:160
struct archt * other_arch
Definition: object.h:413
Definition: object.h:465
int8_t tail_y
Definition: object.h:471
#define FLAG_REMOVED
Definition: define.h:232
archetype * find_archetype_by_object_type_name(int type, const char *name)
Definition: arch.c:83
#define CALLOC(x, y)
Definition: compat.h:27
int16_t * discrete_damage
Definition: object.h:435
void object_free_drop_inventory(object *ob)
Definition: object.c:1389
const char * title
Definition: object.h:317
int16_t y
Definition: object.h:326
void clear_archetable(void)
Definition: arch.c:207
#define MSG_TYPE_COMMAND
Definition: newclient.h:379
void object_dump(const object *op, StringBuffer *sb)
Definition: object.c:425
EXTERN archetype * empty_archetype
Definition: global.h:149
static void load_archetypes(void)
Definition: arch.c:534
#define ARCHTABLE
Definition: config.h:528
#define LL_NORMAL
Definition: loader.h:12
object * object_new(void)
Definition: object.c:1068
const char * name_pl
Definition: object.h:315
object * create_archetype(const char *name)
Definition: arch.c:620
void dump_arch(archetype *at, StringBuffer *sb)
Definition: arch.c:235
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2710
float speed_left
Definition: object.h:329
static void second_arch_pass(FILE *fp)
Definition: arch.c:416
#define LO_NEWFILE
Definition: loader.h:17
#define LL_MORE
Definition: loader.h:11
void free_arch(archetype *at)
Definition: arch.c:265
#define snprintf
Definition: win32.h:46
archetype * get_archetype_by_skill_name(const char *skill, int type)
Definition: arch.c:107
static int arch_cmp
Definition: arch.c:39
const char * name
Definition: object.h:311
struct archt * more
Definition: object.h:469
void load_treasures(void)
Definition: treasure.c:219
archetype * find_archetype_by_object_name(const char *name)
Definition: arch.c:57
struct archt * head
Definition: object.h:468
void object_clear(object *op)
Definition: object.c:790
const char * archetypes
Definition: global.h:246
archetype * try_find_archetype(const char *name)
Definition: arch.c:666
static unsigned long hasharch(const char *str, int tablesize)
Definition: arch.c:639
void check_generators(void)
Definition: arch.c:469
Definition: object.h:214
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
#define MSG_TYPE_COMMAND_DEBUG
Definition: newclient.h:508
#define MAX_BUF
Definition: define.h:35
object * object_create_arch(archetype *at)
Definition: arch.c:736
int16_t x
Definition: object.h:326
void free_all_archs(void)
Definition: arch.c:289
const char * skill
Definition: object.h:321
const char * datadir
Definition: global.h:242
#define FLAG_GENERATOR
Definition: define.h:248
archetype * get_archetype_by_type_subtype(int type, int subtype)
Definition: arch.c:136
int load_object(FILE *fp, object *op, int bufstate, int map_flags)
struct archt * arch
Definition: object.h:412
#define MAXSTRING
Definition: config.h:529
uint8_t type
Definition: object.h:338
struct Settings settings
Definition: init.c:40
void arch_info(object *op)
Definition: arch.c:198
struct archt * next
Definition: object.h:467
const char * msg
Definition: object.h:322
sstring add_string(const char *str)
Definition: shstr.c:124
#define FLAG_MONSTER
Definition: define.h:245
struct obj * inv
Definition: object.h:290
#define NDI_UNIQUE
Definition: newclient.h:245
struct obj * head
Definition: object.h:296
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
const New_Face * face
Definition: object.h:332
#define FLAG_NO_PICK
Definition: define.h:239
void object_free_key_values(object *op)
Definition: object.c:758
#define SP_SUMMON_GOLEM
Definition: spells.h:86
EXTERN archetype * first_archetype
Definition: global.h:122
struct obj * more
Definition: object.h:295
object * arch_to_object(archetype *at)
Definition: arch.c:571
#define FLAG_CONTENT_ON_GEN
Definition: define.h:374
archetype * get_archetype_struct(void)
Definition: arch.c:314
const char * name
Definition: object.h:466
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
#define FLAG_FREED
Definition: define.h:233