Crossfire Server, Branches 1.12  R18729
arch.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_arch_c =
3  * "$Id: arch.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2002-2006 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
43 #include <global.h>
44 #include <loader.h>
45 
47 #define TIME_ARCH_LOAD 0
48 
49 static void add_arch(archetype *at);
50 
52 static int arch_cmp = 0;
53 static int arch_search = 0;
54 int arch_init;
56 static void load_archetypes(void);
57 
71  archetype *at;
72  const char *tmp;
73 
74  if (name == NULL)
75  return (archetype *)NULL;
76  tmp = add_string(name);
77  for (at = first_archetype; at != NULL; at = at->next) {
78  if (at->clone.name == tmp) {
79  free_string(tmp);
80  return at;
81  }
82  }
83  free_string(tmp);
84  return NULL;
85 }
86 
96 archetype *find_archetype_by_object_type_name(int type, const char *name) {
97  archetype *at;
98 
99  if (name == NULL)
100  return NULL;
101 
102  for (at = first_archetype; at != NULL; at = at->next) {
103  if (at->clone.type == type && strcmp(at->clone.name, name) == 0)
104  return at;
105  }
106 
107  return NULL;
108 }
109 
120 archetype *get_archetype_by_skill_name(const char *skill, int type) {
121  archetype *at;
122 
123  if (skill == NULL)
124  return NULL;
125 
126  for (at = first_archetype; at != NULL; at = at->next) {
127  if (((type == -1) || (type == at->clone.type))
128  && (at->clone.skill) && (!strcmp(at->clone.skill, skill)))
129  return at;
130  }
131  return NULL;
132 }
133 
149 archetype *get_archetype_by_type_subtype(int type, int subtype) {
150  archetype *at;
151 
152  for (at = first_archetype; at != NULL; at = at->next) {
153  if (((type == -1) || (type == at->clone.type))
154  && (subtype == -1 || subtype == at->clone.subtype))
155  return at;
156  }
157  return NULL;
158 }
159 
173 object *create_archetype_by_object_name(const char *name) {
174  archetype *at;
175  char tmpname[MAX_BUF];
176  size_t i;
177 
178  strncpy(tmpname, name, MAX_BUF-1);
179  tmpname[MAX_BUF-1] = 0;
180  for (i = strlen(tmpname); i > 0; i--) {
181  tmpname[i] = 0;
182  at = find_archetype_by_object_name(tmpname);
183  if (at != NULL) {
184  return arch_to_object(at);
185  }
186  }
187  return create_singularity(name);
188 }
189 
195 void init_archetypes(void) {
196  if (first_archetype != NULL) /* Only do this once */
197  return;
198  arch_init = 1;
199  load_archetypes();
200  arch_init = 0;
201  empty_archetype = find_archetype("empty_archetype");
202  /* init_blocksview();*/
203 }
204 
209 void arch_info(object *op) {
211  "%d searches and %d strcmp()'s",
212  "%d searches and %d strcmp()'s",
214 }
215 
219 void clear_archetable(void) {
220  memset((void *)arch_table, 0, ARCHTABLE*sizeof(archetype *));
221 }
222 
226 static void init_archetable(void) {
227  archetype *at;
228 
229  LOG(llevDebug, " Setting up archetable...\n");
230  for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
231  add_arch(at);
232  LOG(llevDebug, "done\n");
233 }
234 
244  dump_object(&at->clone, sb);
245 }
246 
253  archetype *at;
254 
255  for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) {
256  StringBuffer *sb;
257  char *diff;
258 
259  sb = stringbuffer_new();
260  dump_arch(at, sb);
261  diff = stringbuffer_finish(sb);
262  LOG(llevDebug, "%s\n", diff);
263  free(diff);
264  }
265 }
266 
273 void free_arch(archetype *at) {
274  if (at->name)
275  free_string(at->name);
276  if (at->clone.name)
277  free_string(at->clone.name);
278  if (at->clone.name_pl)
280  if (at->clone.title)
281  free_string(at->clone.title);
282  if (at->clone.race)
283  free_string(at->clone.race);
284  if (at->clone.slaying)
286  if (at->clone.msg)
287  free_string(at->clone.msg);
288  if (at->clone.discrete_damage)
289  free(at->clone.discrete_damage);
290  free_key_values(&at->clone);
291  free(at);
292 }
293 
298 void free_all_archs(void) {
299  archetype *at, *next;
300  int i = 0;
301 
302  for (at = first_archetype; at != NULL; at = next) {
303  if (at->more)
304  next = at->more;
305  else
306  next = at->next;
307  free_arch(at);
308  i++;
309  }
310  first_archetype = NULL;
311  /* Reset the hashtable */
313  LOG(llevDebug, "Freed %d archetypes\n", i);
314 }
315 
324  archetype *new;
325 
326  new = (archetype *)CALLOC(1, sizeof(archetype));
327  if (new == NULL)
329  new->next = NULL;
330  new->name = NULL;
331  new->clone.other_arch = NULL;
332  new->clone.name = NULL;
333  new->clone.name_pl = NULL;
334  new->clone.title = NULL;
335  new->clone.race = NULL;
336  new->clone.slaying = NULL;
337  new->clone.msg = NULL;
338  clear_object(&new->clone); /* to initial state other also */
339  CLEAR_FLAG((&new->clone), FLAG_FREED); /* This shouldn't matter, since copy_object() */
340  SET_FLAG((&new->clone), FLAG_REMOVED); /* doesn't copy these flags... */
341  new->head = NULL;
342  new->more = NULL;
343  new->clone.arch = new;
344  return new;
345 }
346 
357 static void first_arch_pass(FILE *fp) {
358  object *op;
359  archetype *at, *head = NULL, *last_more = NULL;
360  int i, first = 2;
361 
362  op = get_object();
364 
365  while ((i = load_object(fp, op, first, 0))) {
366  first = 0;
367  copy_object(op, &at->clone);
368  at->clone.speed_left = (float)(-0.1);
369  /* copy the body_info to the body_used - this is only really
370  * need for monsters, but doesn't hurt to do it for everything.
371  * by doing so, when a monster is created, it has good starting
372  * values for the body_used info, so when items are created
373  * for it, they can be properly equipped.
374  */
375  memcpy(&at->clone.body_used, &op->body_info, sizeof(op->body_info));
376 
377  switch (i) {
378  case LL_NORMAL: /* A new archetype, just link it with the previous */
379  if (last_more != NULL)
380  last_more->next = at;
381  if (head != NULL)
382  head->next = at;
383  head = last_more = at;
384  at->tail_x = 0;
385  at->tail_y = 0;
386  break;
387 
388  case LL_MORE: /* Another part of the previous archetype, link it correctly */
389  at->head = head;
390  at->clone.head = &head->clone;
391  if (last_more != NULL) {
392  last_more->more = at;
393  last_more->clone.more = &at->clone;
394  }
395  last_more = at;
396 
397  /* Set FLAG_MONSTER throughout parts if head has it */
398  if (QUERY_FLAG(&head->clone, FLAG_MONSTER)) {
399  SET_FLAG(&at->clone, FLAG_MONSTER);
400  }
401 
402  /* If this multipart image is still composed of individual small
403  * images, don't set the tail_.. values. We can't use them anyways,
404  * and setting these to zero makes the map sending to the client much
405  * easier as just looking at the head, we know what to do.
406  */
407  if (at->clone.face != head->clone.face) {
408  head->tail_x = 0;
409  head->tail_y = 0;
410  } else {
411  if (at->clone.x > head->tail_x)
412  head->tail_x = at->clone.x;
413  if (at->clone.y > head->tail_y)
414  head->tail_y = at->clone.y;
415  }
416  break;
417  }
418 
419  at = get_archetype_struct();
420  clear_object(op);
421  op->arch = at;
422  }
423  free_object(op);
424  op->arch = NULL; /* arch is checked for temporary archetypes if not NULL. */
425  free(at);
426 }
427 
437 static void second_arch_pass(FILE *fp) {
438  char buf[MAX_BUF], *variable = buf, *argument, *cp;
439  archetype *at = NULL, *other;
440  object *inv;
441 
442  while (fgets(buf, MAX_BUF, fp) != NULL) {
443  if (*buf == '#')
444  continue;
445  if ((argument = strchr(buf, ' ')) != NULL) {
446  *argument = '\0', argument++;
447  cp = argument+strlen(argument)-1;
448  while (isspace(*cp)) {
449  *cp = '\0';
450  cp--;
451  }
452  }
453  if (!strcmp("Object", variable)) {
454  if ((at = find_archetype(argument)) == NULL)
455  LOG(llevError, "Warning: failed to find arch %s\n", argument);
456  } else if (!strcmp("other_arch", variable)) {
457  if (at != NULL && at->clone.other_arch == NULL) {
458  if ((other = find_archetype(argument)) == NULL)
459  LOG(llevError, "Warning: failed to find other_arch %s\n", argument);
460  else if (at != NULL)
461  at->clone.other_arch = other;
462  }
463  } else if (!strcmp("randomitems", variable)) {
464  if (at != NULL) {
465  treasurelist *tl = find_treasurelist(argument);
466  if (tl == NULL)
467  LOG(llevError, "Failed to link treasure to arch (%s): %s\n", at->name, argument);
468  else
469  at->clone.randomitems = tl;
470  }
471  } else if (!strcmp("arch", variable)) {
472  inv = create_archetype(argument);
473  load_object(fp, inv, LO_LINEMODE, 0);
474  if (at) {
475  insert_ob_in_ob(inv, &at->clone);
476  /*LOG(llevDebug, "Put %s in %s\n", inv->name, at->clone.name);*/
477  } else {
478  LOG(llevError, "Got an arch %s not inside an Object.\n", argument);
479  free_object(inv);
480  }
481  }
482  }
483 }
484 
485 #ifdef DEBUG
486 
491 void check_generators(void) {
492  archetype *at;
493 
494  for (at = first_archetype; at != NULL; at = at->next)
495  if (QUERY_FLAG(&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL)
496  LOG(llevError, "Warning: %s is generator but lacks other_arch.\n", at->name);
497 }
498 #endif
499 
507 static void load_archetypes(void) {
508  FILE *fp;
509  char filename[MAX_BUF];
510  int comp;
511 #if TIME_ARCH_LOAD
512  struct timeval tv1, tv2;
513 #endif
514 
515  snprintf(filename, sizeof(filename), "%s/%s", settings.datadir, settings.archetypes);
516  LOG(llevDebug, "Reading archetypes from %s...\n", filename);
517  if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
518  LOG(llevError, " Can't open archetype file.\n");
519  return;
520  }
522  LOG(llevDebug, " arch-pass 1...\n");
523 #if TIME_ARCH_LOAD
524  GETTIMEOFDAY(&tv1);
525 #endif
526  first_arch_pass(fp);
527 #if TIME_ARCH_LOAD
528  {
529  int sec, usec;
530 
531  GETTIMEOFDAY(&tv2);
532  sec = tv2.tv_sec-tv1.tv_sec;
533  usec = tv2.tv_usec-tv1.tv_usec;
534  if (usec < 0) {
535  usec += 1000000;
536  sec--;
537  }
538  LOG(llevDebug, "Load took %d.%06d seconds\n", sec, usec);
539  }
540 #endif
541 
542  LOG(llevDebug, " done\n");
543  init_archetable();
544  warn_archetypes = 1;
545 
546  /* do a close and reopen instead of a rewind - necessary in case the
547  * file has been compressed.
548  */
549  close_and_delete(fp, comp);
550  fp = open_and_uncompress(filename, 0, &comp);
551 
552  LOG(llevDebug, " loading treasure...\n");
553  load_treasures();
554  LOG(llevDebug, " done\n");
555  LOG(llevDebug, "arch-pass 2...\n");
556  second_arch_pass(fp);
557  LOG(llevDebug, " done\n");
558 #ifdef DEBUG
560 #endif
561  close_and_delete(fp, comp);
562  LOG(llevDebug, " done\n");
563 }
564 
576 object *arch_to_object(archetype *at) {
577  object *op;
578 
579  if (at == NULL) {
580  if (warn_archetypes)
581  LOG(llevError, "Couldn't find archetype.\n");
582  return NULL;
583  }
584  op = get_object();
585  copy_object_with_inv(&at->clone, op);
586  op->arch = at;
587  return op;
588 }
589 
603 object *create_singularity(const char *name) {
604  object *op;
605  char buf[MAX_BUF];
606 
607  snprintf(buf, sizeof(buf), "%s (%s)", ARCH_SINGULARITY, name);
608  op = get_object();
609  op->name = add_string(buf);
610  op->name_pl = add_string(buf);
611  SET_FLAG(op, FLAG_NO_PICK);
612  return op;
613 }
614 
625 object *create_archetype(const char *name) {
626  archetype *at;
627 
628  at = find_archetype(name);
629  if (at == NULL)
630  return create_singularity(name);
631  return arch_to_object(at);
632 }
633 
643 static unsigned long
644 hasharch(const char *str, int tablesize) {
645  unsigned long hash = 0;
646  int i = 0;
647  const char *p;
648 
649  /* use the one-at-a-time hash function, which supposedly is
650  * better than the djb2-like one used by perl5.005, but
651  * certainly is better then the bug used here before.
652  * see http://burtleburtle.net/bob/hash/doobs.html
653  */
654  for (p = str; i < MAXSTRING && *p; p++, i++) {
655  hash += *p;
656  hash += hash<<10;
657  hash ^= hash>>6;
658  }
659  hash += hash<<3;
660  hash ^= hash>>11;
661  hash += hash<<15;
662  return hash%tablesize;
663 }
664 
671 archetype *try_find_archetype(const char *name) {
672  archetype *at;
673  unsigned long index;
674 
675  if (name == NULL)
676  return (archetype *)NULL;
677 
678  index = hasharch(name, ARCHTABLE);
679  arch_search++;
680  for (;;) {
681  at = arch_table[index];
682  if (at == NULL) {
683  return NULL;
684  }
685  arch_cmp++;
686  if (!strcmp(at->name, name))
687  return at;
688  if (++index >= ARCHTABLE)
689  index = 0;
690  }
691 }
692 
700 archetype *find_archetype(const char *name) {
701  archetype *at;
702 
703  if (name == NULL)
704  return (archetype *)NULL;
705  at = try_find_archetype(name);
706  if (at == NULL && warn_archetypes)
707  LOG(llevError, "Couldn't find archetype %s\n", name);
708  return at;
709 }
710 
715 static void add_arch(archetype *at) {
716  unsigned long index = hasharch(at->name, ARCHTABLE), org_index = index;
717 
718  for (;;) {
719  if (arch_table[index] == NULL) {
720  arch_table[index] = at;
721  return;
722  }
723  if (++index == ARCHTABLE)
724  index = 0;
725  if (index == org_index)
727  }
728 }
729 
742  object *op, *prev = NULL, *head = NULL;
743 
744  while (at) {
745  op = arch_to_object(at);
746  op->x = at->clone.x;
747  op->y = at->clone.y;
748  if (head)
749  op->head = head, prev->more = op;
750  if (!head)
751  head = op;
752  prev = op;
753  at = at->more;
754  }
755  return (head);
756 }
757 
758 /*** end of arch.c ***/
#define ARCH_SINGULARITY
Definition: object.h:402
archetype * find_archetype(const char *name)
Definition: arch.c:700
#define LO_LINEMODE
Definition: loader.h:44
#define OUT_OF_MEMORY
Definition: define.h:94
static void first_arch_pass(FILE *fp)
Definition: arch.c:357
const char * race
Definition: object.h:171
#define CALLOC(x, y)
Definition: global.h:295
#define SET_FLAG(xyz, p)
Definition: define.h:510
static int arch_search
Definition: arch.c:53
void check_generators(void)
object * create_singularity(const char *name)
Definition: arch.c:603
treasurelist * find_treasurelist(const char *name)
Definition: treasure.c:295
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:64
void free_string(sstring str)
Definition: shstr.c:272
struct treasureliststruct * randomitems
Definition: object.h:236
object clone
Definition: object.h:326
static archetype * arch_table[ARCHTABLE]
Definition: arch.c:51
const char * slaying
Definition: object.h:172
void init_archetypes(void)
Definition: arch.c:195
static void init_archetable(void)
Definition: arch.c:226
static void add_arch(archetype *at)
Definition: arch.c:715
void dump_all_archetypes(void)
Definition: arch.c:252
uint8 subtype
Definition: object.h:190
int arch_init
Definition: arch.c:54
void close_and_delete(FILE *fp, int compressed)
Definition: porting.c:748
object * create_archetype_by_object_name(const char *name)
Definition: arch.c:173
sint16 x
Definition: object.h:179
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
struct archt * other_arch
Definition: object.h:264
Definition: object.h:321
#define FLAG_REMOVED
Definition: define.h:528
archetype * find_archetype_by_object_type_name(int type, const char *name)
Definition: arch.c:96
const char * title
Definition: object.h:170
void clear_archetable(void)
Definition: arch.c:219
EXTERN archetype * empty_archetype
Definition: global.h:227
static void load_archetypes(void)
Definition: arch.c:507
#define ARCHTABLE
Definition: config.h:596
#define LL_NORMAL
Definition: loader.h:40
const char * name_pl
Definition: object.h:168
object * create_archetype(const char *name)
Definition: arch.c:625
void dump_arch(archetype *at, StringBuffer *sb)
Definition: arch.c:243
float speed_left
Definition: object.h:182
static void second_arch_pass(FILE *fp)
Definition: arch.c:437
#define LL_MORE
Definition: loader.h:39
void free_arch(archetype *at)
Definition: arch.c:273
void dump_object(object *op, StringBuffer *sb)
Definition: object.c:372
archetype * get_archetype_by_skill_name(const char *skill, int type)
Definition: arch.c:120
static int arch_cmp
Definition: arch.c:52
const char * name
Definition: object.h:167
struct archt * more
Definition: object.h:325
void load_treasures(void)
Definition: treasure.c:224
archetype * find_archetype_by_object_name(const char *name)
Definition: arch.c:70
void fatal(int err)
Definition: glue.c:60
struct archt * head
Definition: object.h:324
sint16 y
Definition: object.h:179
const char * archetypes
Definition: global.h:338
sint8 tail_y
Definition: object.h:327
archetype * try_find_archetype(const char *name)
Definition: arch.c:671
static unsigned long hasharch(const char *str, int tablesize)
Definition: arch.c:644
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
object * insert_ob_in_ob(object *op, object *where)
Definition: object.c:2510
#define MAX_BUF
Definition: define.h:81
object * object_create_arch(archetype *at)
Definition: arch.c:741
object * get_object(void)
Definition: object.c:921
#define MSG_TYPE_COMMAND_DEBUG
Definition: newclient.h:446
void free_all_archs(void)
Definition: arch.c:298
const char * skill
Definition: object.h:174
#define ARCHTABLE_TOO_SMALL
Definition: define.h:96
const char * datadir
Definition: global.h:334
sint8 body_info[NUM_BODY_LOCATIONS]
Definition: object.h:223
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
sint8 body_used[NUM_BODY_LOCATIONS]
Definition: object.h:224
#define FLAG_GENERATOR
Definition: define.h:544
archetype * get_archetype_by_type_subtype(int type, int subtype)
Definition: arch.c:149
int load_object(FILE *fp, object *op, int bufstate, int map_flags)
struct archt * arch
Definition: object.h:263
#define MAXSTRING
Definition: config.h:597
struct Settings settings
Definition: init.c:48
void arch_info(object *op)
Definition: arch.c:209
void free_key_values(object *op)
Definition: object.c:659
struct archt * next
Definition: object.h:323
#define MSG_TYPE_COMMAND
Definition: newclient.h:326
const char * msg
Definition: object.h:175
#define GETTIMEOFDAY(last_time)
Definition: global.h:442
sstring add_string(const char *str)
Definition: shstr.c:116
void copy_object_with_inv(object *src_ob, object *dest_ob)
Definition: object.c:862
void clear_object(object *op)
Definition: object.c:688
#define FLAG_MONSTER
Definition: define.h:541
#define NDI_UNIQUE
Definition: newclient.h:219
struct obj * head
Definition: object.h:154
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
EXTERN long warn_archetypes
Definition: global.h:208
void copy_object(object *op2, object *op)
Definition: object.c:758
sint8 tail_x
Definition: object.h:327
void free_object(object *ob)
Definition: object.c:1238
New_Face * face
Definition: object.h:183
#define FLAG_NO_PICK
Definition: define.h:535
sint16 * discrete_damage
Definition: object.h:291
EXTERN archetype * first_archetype
Definition: global.h:195
struct obj * more
Definition: object.h:153
object * arch_to_object(archetype *at)
Definition: arch.c:576
FILE * open_and_uncompress(const char *name, int flag, int *compressed)
Definition: porting.c:724
archetype * get_archetype_struct(void)
Definition: arch.c:323
const char * name
Definition: object.h:322
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:78
uint8 type
Definition: object.h:189
#define FLAG_FREED
Definition: define.h:529