ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/arch.C
(Generate patch)

Comparing deliantra/server/common/arch.C (file contents):
Revision 1.14 by root, Fri Sep 8 17:14:07 2006 UTC vs.
Revision 1.17 by root, Tue Sep 12 19:20:06 2006 UTC

1/*
2 * static char *rcsid_arch_c =
3 * "$Id: arch.C,v 1.14 2006/09/08 17:14:07 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
36#include <loader.h> 31#include <loader.h>
37 32
38/* IF set, does a little timing on the archetype load. */ 33/* IF set, does a little timing on the archetype load. */
39#define TIME_ARCH_LOAD 0 34#define TIME_ARCH_LOAD 0
40 35
41static void add_arch (archetype * at); 36static void add_arch (archetype *at);
42 37
43static archetype *arch_table[ARCHTABLE]; 38static archetype *arch_table[ARCHTABLE];
44int arch_cmp = 0; /* How many strcmp's */ 39int arch_cmp = 0; /* How many strcmp's */
45int arch_search = 0; /* How many searches */ 40int arch_search = 0; /* How many searches */
46int arch_init; /* True if doing arch initialization */ 41int arch_init; /* True if doing arch initialization */
53 * MSW 2003-04-29 48 * MSW 2003-04-29
54 */ 49 */
55 50
56#if USE_UNORDERED_MAP 51#if USE_UNORDERED_MAP
57// the hashtable 52// the hashtable
58typedef std::tr1::unordered_map<size_t, archetype *> HT; 53typedef
54 std::tr1::unordered_map <
55size_t, archetype *>
56 HT;
59 57
60static HT ht; 58static
59 HT
60 ht;
61#endif 61#endif
62 62
63/** 63/**
64 * GROS - This function retrieves an archetype given the name that appears 64 * GROS - This function retrieves an archetype given the name that appears
65 * during the game (for example, "writing pen" instead of "stylus"). 65 * during the game (for example, "writing pen" instead of "stylus").
72 * - the archetype found or null if nothing was found. 72 * - the archetype found or null if nothing was found.
73 */ 73 */
74archetype * 74archetype *
75find_archetype_by_object_name (const char *name) 75find_archetype_by_object_name (const char *name)
76{ 76{
77 archetype *at; 77 archetype *
78 at;
78 79
79 if (name == NULL) 80 if (name == NULL)
80 return (archetype *) NULL; 81 return (archetype *) NULL;
81 82
82 for (at = first_archetype; at != NULL; at = at->next) 83 for (at = first_archetype; at != NULL; at = at->next)
93 * except that it considers only items of the given type. 94 * except that it considers only items of the given type.
94 */ 95 */
95archetype * 96archetype *
96find_archetype_by_object_type_name (int type, const char *name) 97find_archetype_by_object_type_name (int type, const char *name)
97{ 98{
98 archetype *at; 99 archetype *
100 at;
99 101
100 if (name == NULL) 102 if (name == NULL)
101 return NULL; 103 return NULL;
102 104
103 for (at = first_archetype; at != NULL; at = at->next) 105 for (at = first_archetype; at != NULL; at = at->next)
165 * but it otherwise had a big memory leak. 167 * but it otherwise had a big memory leak.
166 */ 168 */
167object * 169object *
168get_archetype_by_object_name (const char *name) 170get_archetype_by_object_name (const char *name)
169{ 171{
170 archetype * 172 archetype *at;
171 at;
172 char
173 tmpname[MAX_BUF]; 173 char tmpname[MAX_BUF];
174 int 174 int i;
175 i;
176 175
177 strncpy (tmpname, name, MAX_BUF - 1); 176 assign (tmpname, name);
178 tmpname[MAX_BUF - 1] = 0; 177
179 for (i = strlen (tmpname); i > 0; i--) 178 for (i = strlen (tmpname); i > 0; i--)
180 { 179 {
181 tmpname[i] = 0; 180 tmpname[i] = 0;
182 at = find_archetype_by_object_name (tmpname); 181 at = find_archetype_by_object_name (tmpname);
182
183 if (at != NULL) 183 if (at != NULL)
184 { 184 {
185 return arch_to_object (at); 185 return arch_to_object (at);
186 } 186 }
187 } 187 }
188
188 return create_singularity (name); 189 return create_singularity (name);
189} 190}
190 191
191 /* This is a subset of the parse_id command. Basically, name can be 192 /* This is a subset of the parse_id command. Basically, name can be
192 * a string seperated lists of things to match, with certain keywords. 193 * a string seperated lists of things to match, with certain keywords.
204 * If count is 1, make a quick check on the name. 205 * If count is 1, make a quick check on the name.
205 * IF count is >1, we need to make plural name. Return if match. 206 * IF count is >1, we need to make plural name. Return if match.
206 * Last, make a check on the full name. 207 * Last, make a check on the full name.
207 */ 208 */
208int 209int
209item_matched_string (object * pl, object * op, const char *name) 210item_matched_string (object *pl, object *op, const char *name)
210{ 211{
211 char * 212 char *
212 cp, 213 cp,
213 local_name[MAX_BUF]; 214 local_name[MAX_BUF];
214 int 215 int
215 count, 216 count,
216 retval = 0; 217 retval = 0;
218
217 strcpy (local_name, name); /* strtok is destructive to name */ 219 strcpy (local_name, name); /* strtok is destructive to name */
218 220
219 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ",")) 221 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ","))
220 { 222 {
221 while (cp[0] == ' ') 223 while (cp[0] == ' ')
326 return; 328 return;
327 arch_init = 1; 329 arch_init = 1;
328 load_archetypes (); 330 load_archetypes ();
329 arch_init = 0; 331 arch_init = 0;
330 empty_archetype = find_archetype ("empty_archetype"); 332 empty_archetype = find_archetype ("empty_archetype");
333
331/* init_blocksview();*/ 334/* init_blocksview();*/
332} 335}
333 336
334/* 337/*
335 * Stores debug-information about how efficient the hashtable 338 * Stores debug-information about how efficient the hashtable
336 * used for archetypes has been in the static errmsg array. 339 * used for archetypes has been in the static errmsg array.
337 */ 340 */
338 341
339void 342void
340arch_info (object * op) 343arch_info (object *op)
341{ 344{
342 sprintf (errmsg, "%d searches and %d strcmp()'s", arch_search, arch_cmp); 345 sprintf (errmsg, "%d searches and %d strcmp()'s", arch_search, arch_cmp);
343 new_draw_info (NDI_BLACK, 0, op, errmsg); 346 new_draw_info (NDI_BLACK, 0, op, errmsg);
344} 347}
345 348
358 */ 361 */
359 362
360void 363void
361init_archetable (void) 364init_archetable (void)
362{ 365{
363 archetype *at; 366 archetype *
367 at;
364 368
365 LOG (llevDebug, " Setting up archetable...\n"); 369 LOG (llevDebug, " Setting up archetable...\n");
366 370
367 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 371 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
368 add_arch (at); 372 add_arch (at);
373/* 377/*
374 * Dumps an archetype to debug-level output. 378 * Dumps an archetype to debug-level output.
375 */ 379 */
376 380
377void 381void
378dump_arch (archetype * at) 382dump_arch (archetype *at)
379{ 383{
380 dump_object (&at->clone); 384 dump_object (&at->clone);
381} 385}
382 386
383/* 387/*
389void 393void
390dump_all_archetypes (void) 394dump_all_archetypes (void)
391{ 395{
392 archetype * 396 archetype *
393 at; 397 at;
398
394 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 399 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
395 { 400 {
396 dump_arch (at); 401 dump_arch (at);
397 fprintf (logfile, "%s\n", errmsg); 402 fprintf (logfile, "%s\n", errmsg);
398 } 403 }
414 else 419 else
415 next = at->next; 420 next = at->next;
416 421
417 delete 422 delete
418 at; 423 at;
424
419 i++; 425 i++;
420 } 426 }
421 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 427 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
422} 428}
423 429
424archetype::archetype () 430archetype::archetype ()
425{ 431{
426 clear_object (&clone); /* to initial state other also */ 432 clear_object (&clone); /* to initial state other also */
427 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_object() */ 433 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_object() */
428 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */ 434 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */
429} 435}
430 436
431archetype::~archetype () 437archetype::~archetype ()
432{ 438{
433} 439}
437 * of archetype-structures. 443 * of archetype-structures.
438 */ 444 */
439void 445void
440first_arch_pass (object_thawer & fp) 446first_arch_pass (object_thawer & fp)
441{ 447{
448 archetype *
449 at, *
442 archetype *at, *head = NULL, *last_more = NULL; 450 head = NULL, *last_more = NULL;
443 451
444 at->clone.arch = first_archetype = at = new archetype; 452 at->clone.arch = first_archetype = at = new archetype;
445 453
446 while (int i = load_object (fp, &at->clone, 0)) 454 while (int i = load_object (fp, &at->clone, 0))
447 { 455 {
454 */ 462 */
455 memcpy (&at->clone.body_used, &at->clone.body_info, sizeof (at->clone.body_info)); 463 memcpy (&at->clone.body_used, &at->clone.body_info, sizeof (at->clone.body_info));
456 464
457 switch (i) 465 switch (i)
458 { 466 {
459 case LL_NORMAL: /* A new archetype, just link it with the previous */ 467 case LL_NORMAL: /* A new archetype, just link it with the previous */
460 if (last_more != NULL) 468 if (last_more != NULL)
461 last_more->next = at; 469 last_more->next = at;
462 if (head != NULL) 470 if (head != NULL)
463 head->next = at; 471 head->next = at;
464 head = last_more = at; 472 head = last_more = at;
465#if 0 473#if 0
466 if (!op->type) 474 if (!op->type)
467 LOG (llevDebug, " WARNING: Archetype %s has no type info!\n", op->arch->name); 475 LOG (llevDebug, " WARNING: Archetype %s has no type info!\n", op->arch->name);
468#endif 476#endif
469 at->tail_x = 0; 477 at->tail_x = 0;
470 at->tail_y = 0; 478 at->tail_y = 0;
471 break; 479 break;
472 480
473 case LL_MORE: /* Another part of the previous archetype, link it correctly */ 481 case LL_MORE: /* Another part of the previous archetype, link it correctly */
474 482
475 at->head = head; 483 at->head = head;
476 at->clone.head = &head->clone; 484 at->clone.head = &head->clone;
477 if (last_more != NULL) 485 if (last_more != NULL)
478 { 486 {
479 last_more->more = at; 487 last_more->more = at;
480 last_more->clone.more = &at->clone; 488 last_more->clone.more = &at->clone;
481 } 489 }
482 last_more = at; 490 last_more = at;
483 491
484 /* If this multipart image is still composed of individual small 492 /* If this multipart image is still composed of individual small
485 * images, don't set the tail_.. values. We can't use them anyways, 493 * images, don't set the tail_.. values. We can't use them anyways,
486 * and setting these to zero makes the map sending to the client much 494 * and setting these to zero makes the map sending to the client much
487 * easier as just looking at the head, we know what to do. 495 * easier as just looking at the head, we know what to do.
488 */ 496 */
489 if (at->clone.face != head->clone.face) 497 if (at->clone.face != head->clone.face)
490 { 498 {
491 head->tail_x = 0; 499 head->tail_x = 0;
492 head->tail_y = 0; 500 head->tail_y = 0;
493 } 501 }
494 else 502 else
495 { 503 {
496 if (at->clone.x > head->tail_x) 504 if (at->clone.x > head->tail_x)
497 head->tail_x = at->clone.x; 505 head->tail_x = at->clone.x;
498 if (at->clone.y > head->tail_y) 506 if (at->clone.y > head->tail_y)
499 head->tail_y = at->clone.y; 507 head->tail_y = at->clone.y;
500 } 508 }
501 break; 509 break;
502 510
503 } 511 }
504 512
505 at = new archetype; 513 at = new archetype;
514
506 at->clone.arch = at; 515 at->clone.arch = at;
507 } 516 }
508 517
509 delete at; 518 delete at;
510} 519}
515 */ 524 */
516 525
517void 526void
518second_arch_pass (object_thawer & thawer) 527second_arch_pass (object_thawer & thawer)
519{ 528{
529 char
530 buf[MAX_BUF], *
520 char buf[MAX_BUF], *variable = buf, *argument, *cp; 531 variable = buf, *argument, *cp;
532 archetype *
521 archetype *at = NULL, *other; 533 at = NULL, *other;
522 534
523 while (fgets (buf, MAX_BUF, thawer) != NULL) 535 while (fgets (buf, MAX_BUF, thawer) != NULL)
524 { 536 {
525 if (*buf == '#') 537 if (*buf == '#')
526 continue; 538 continue;
553 { 565 {
554 if (at != NULL) 566 if (at != NULL)
555 { 567 {
556 treasurelist * 568 treasurelist *
557 tl = find_treasurelist (argument); 569 tl = find_treasurelist (argument);
570
558 if (tl == NULL) 571 if (tl == NULL)
559 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument); 572 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument);
560 else 573 else
561 at->clone.randomitems = tl; 574 at->clone.randomitems = tl;
562 } 575 }
568void 581void
569check_generators (void) 582check_generators (void)
570{ 583{
571 archetype * 584 archetype *
572 at; 585 at;
586
573 for (at = first_archetype; at != NULL; at = at->next) 587 for (at = first_archetype; at != NULL; at = at->next)
574 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL) 588 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL)
575 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name); 589 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
576} 590}
577#endif 591#endif
586void 600void
587load_archetypes (void) 601load_archetypes (void)
588{ 602{
589 char 603 char
590 filename[MAX_BUF]; 604 filename[MAX_BUF];
605
591#if TIME_ARCH_LOAD 606#if TIME_ARCH_LOAD
592 struct timeval 607 struct timeval
593 tv1, 608 tv1,
594 tv2; 609 tv2;
595#endif 610#endif
630 * Creates and returns a new object which is a copy of the given archetype. 645 * Creates and returns a new object which is a copy of the given archetype.
631 * This function returns NULL on failure. 646 * This function returns NULL on failure.
632 */ 647 */
633 648
634object * 649object *
635arch_to_object (archetype * at) 650arch_to_object (archetype *at)
636{ 651{
637 object * 652 object *
638 op; 653 op;
654
639 if (at == NULL) 655 if (at == NULL)
640 { 656 {
641 if (warn_archetypes) 657 if (warn_archetypes)
642 LOG (llevError, "Couldn't find archetype.\n"); 658 LOG (llevError, "Couldn't find archetype.\n");
659
643 return NULL; 660 return NULL;
644 } 661 }
662
645 op = get_object (); 663 op = get_object ();
646 copy_object (&at->clone, op); 664 copy_object (&at->clone, op);
665 op->arch = at;
647 op->instantiate (); 666 op->instantiate ();
648 op->arch = at;
649 return op; 667 return op;
650} 668}
651 669
652/* 670/*
653 * Creates an object. This function is called by get_archetype() 671 * Creates an object. This function is called by get_archetype()
657 */ 675 */
658 676
659object * 677object *
660create_singularity (const char *name) 678create_singularity (const char *name)
661{ 679{
662 object *op; 680 object *
681 op;
682 char
663 char buf[MAX_BUF]; 683 buf[MAX_BUF];
684
664 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 685 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
665 op = get_object (); 686 op = get_object ();
666 op->name = op->name_pl = buf; 687 op->name = op->name_pl = buf;
667 SET_FLAG (op, FLAG_NO_PICK); 688 SET_FLAG (op, FLAG_NO_PICK);
668 return op; 689 return op;
674 */ 695 */
675 696
676object * 697object *
677get_archetype (const char *name) 698get_archetype (const char *name)
678{ 699{
679 archetype *at; 700 archetype *
701 at;
702
680 at = find_archetype (name); 703 at = find_archetype (name);
681 if (at == NULL) 704 if (at == NULL)
682 return create_singularity (name); 705 return create_singularity (name);
706
683 return arch_to_object (at); 707 return arch_to_object (at);
684} 708}
685 709
686/* 710/*
687 * Hash-function used by the arch-hashtable. 711 * Hash-function used by the arch-hashtable.
688 */ 712 */
689 713
690unsigned long 714unsigned long
691hasharch (const char *str, int tablesize) 715hasharch (const char *str, int tablesize)
692{ 716{
693 unsigned long hash = 0; 717 unsigned long
718 hash = 0;
694 unsigned int i = 0; 719 unsigned int
720 i = 0;
695 const char *p; 721 const char *
722 p;
696 723
697 /* use the one-at-a-time hash function, which supposedly is 724 /* use the one-at-a-time hash function, which supposedly is
698 * better than the djb2-like one used by perl5.005, but 725 * better than the djb2-like one used by perl5.005, but
699 * certainly is better then the bug used here before. 726 * certainly is better then the bug used here before.
700 * see http://burtleburtle.net/bob/hash/doobs.html 727 * see http://burtleburtle.net/bob/hash/doobs.html
725 name = shstr::find (name); 752 name = shstr::find (name);
726 753
727 if (!name) 754 if (!name)
728 return 0; 755 return 0;
729 756
730 HT::const_iterator i = ht.find ((size_t)name); 757 HT::const_iterator i = ht.find ((size_t) name);
731 758
732 if (i == ht.end ()) 759 if (i == ht.end ())
733 return 0; 760 return 0;
734 else 761 else
735 return i->second; 762 return i->second;
736#endif 763#endif
737 764
738 archetype *at; 765 archetype *
766 at;
739 unsigned long index; 767 unsigned long
768 index;
740 769
741 if (name == NULL) 770 if (name == NULL)
742 return (archetype *) NULL; 771 return (archetype *) NULL;
743 772
744 index = hasharch (name, ARCHTABLE); 773 index = hasharch (name, ARCHTABLE);
766 795
767static void 796static void
768add_arch (archetype *at) 797add_arch (archetype *at)
769{ 798{
770#if USE_UNORDERED_MAP 799#if USE_UNORDERED_MAP
771 ht.insert (std::make_pair ((size_t)(const char *)at->name, at)); 800 ht.insert (std::make_pair ((size_t) (const char *) at->name, at));
772#endif 801#endif
773 802
803 int
774 int index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 804 index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index;
775 805
776 for (;;) 806 for (;;)
777 { 807 {
778 if (arch_table[index] == NULL) 808 if (arch_table[index] == NULL)
779 { 809 {
834/* 864/*
835 * member: make instance from class 865 * member: make instance from class
836 */ 866 */
837 867
838object * 868object *
839object_create_arch (archetype * at) 869object_create_arch (archetype *at)
840{ 870{
841 object * 871 object *
842 op, * 872 op, *
843 prev = NULL, *head = NULL; 873 prev = NULL, *head = NULL;
844 874

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines