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.15 by root, Sun Sep 10 13:20:12 2006 UTC vs.
Revision 1.22 by root, Thu Sep 14 22:35:53 2006 UTC

1
2/*
3 * static char *rcsid_arch_c =
4 * "$Id: arch.C,v 1.15 2006/09/10 13:20:12 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
28*/ 22*/
29 23
30#include <cassert> 24#include <cassert>
31 25
32#include <tr1/unordered_map> 26#include <tr1/unordered_map>
54 * MSW 2003-04-29 48 * MSW 2003-04-29
55 */ 49 */
56 50
57#if USE_UNORDERED_MAP 51#if USE_UNORDERED_MAP
58// the hashtable 52// the hashtable
59typedef
60 std::tr1::unordered_map < 53typedef std::tr1::unordered_map
61size_t, archetype *> 54 <
55 std::size_t,
56 archetype *,
57 std::hash<size_t>,
58 std::equal_to<size_t>,
59 slice_allocator< std::pair<const std::size_t, archetype *> >
60 true,
62 HT; 61 > HT;
63 62
64static HT 63static HT ht;
65 ht;
66#endif 64#endif
67 65
68/** 66/**
69 * GROS - This function retrieves an archetype given the name that appears 67 * GROS - This function retrieves an archetype given the name that appears
70 * during the game (for example, "writing pen" instead of "stylus"). 68 * during the game (for example, "writing pen" instead of "stylus").
77 * - the archetype found or null if nothing was found. 75 * - the archetype found or null if nothing was found.
78 */ 76 */
79archetype * 77archetype *
80find_archetype_by_object_name (const char *name) 78find_archetype_by_object_name (const char *name)
81{ 79{
82 archetype * 80 archetype *at;
83 at;
84 81
85 if (name == NULL) 82 if (name == NULL)
86 return (archetype *) NULL; 83 return (archetype *) NULL;
87 84
88 for (at = first_archetype; at != NULL; at = at->next) 85 for (at = first_archetype; at != NULL; at = at->next)
99 * except that it considers only items of the given type. 96 * except that it considers only items of the given type.
100 */ 97 */
101archetype * 98archetype *
102find_archetype_by_object_type_name (int type, const char *name) 99find_archetype_by_object_type_name (int type, const char *name)
103{ 100{
104 archetype * 101 archetype *at;
105 at;
106 102
107 if (name == NULL) 103 if (name == NULL)
108 return NULL; 104 return NULL;
109 105
110 for (at = first_archetype; at != NULL; at = at->next) 106 for (at = first_archetype; at != NULL; at = at->next)
172 * but it otherwise had a big memory leak. 168 * but it otherwise had a big memory leak.
173 */ 169 */
174object * 170object *
175get_archetype_by_object_name (const char *name) 171get_archetype_by_object_name (const char *name)
176{ 172{
177 archetype * 173 archetype *at;
178 at;
179 char
180 tmpname[MAX_BUF]; 174 char tmpname[MAX_BUF];
181 int 175 int i;
182 i;
183 176
184 strncpy (tmpname, name, MAX_BUF - 1); 177 assign (tmpname, name);
185 tmpname[MAX_BUF - 1] = 0; 178
186 for (i = strlen (tmpname); i > 0; i--) 179 for (i = strlen (tmpname); i > 0; i--)
187 { 180 {
188 tmpname[i] = 0; 181 tmpname[i] = 0;
189 at = find_archetype_by_object_name (tmpname); 182 at = find_archetype_by_object_name (tmpname);
183
190 if (at != NULL) 184 if (at != NULL)
191 {
192 return arch_to_object (at); 185 return arch_to_object (at);
193 }
194 } 186 }
187
195 return create_singularity (name); 188 return create_singularity (name);
196} 189}
197 190
198 /* This is a subset of the parse_id command. Basically, name can be 191 /* This is a subset of the parse_id command. Basically, name can be
199 * a string seperated lists of things to match, with certain keywords. 192 * a string seperated lists of things to match, with certain keywords.
213 * Last, make a check on the full name. 206 * Last, make a check on the full name.
214 */ 207 */
215int 208int
216item_matched_string (object *pl, object *op, const char *name) 209item_matched_string (object *pl, object *op, const char *name)
217{ 210{
218 char *
219 cp,
220 local_name[MAX_BUF]; 211 char *cp, local_name[MAX_BUF];
221 int 212 int count, retval = 0;
222 count,
223 retval = 0;
224 213
225 strcpy (local_name, name); /* strtok is destructive to name */ 214 strcpy (local_name, name); /* strtok is destructive to name */
226 215
227 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ",")) 216 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ","))
228 { 217 {
330void 319void
331init_archetypes (void) 320init_archetypes (void)
332{ /* called from add_player() and edit() */ 321{ /* called from add_player() and edit() */
333 if (first_archetype != NULL) /* Only do this once */ 322 if (first_archetype != NULL) /* Only do this once */
334 return; 323 return;
324
335 arch_init = 1; 325 arch_init = 1;
336 load_archetypes (); 326 load_archetypes ();
337 arch_init = 0; 327 arch_init = 0;
338 empty_archetype = find_archetype ("empty_archetype"); 328 empty_archetype = archetype::find ("empty_archetype");
339 329
340/* init_blocksview();*/ 330/* init_blocksview();*/
341} 331}
342 332
343/* 333/*
367 */ 357 */
368 358
369void 359void
370init_archetable (void) 360init_archetable (void)
371{ 361{
372 archetype * 362 archetype *at;
373 at;
374 363
375 LOG (llevDebug, " Setting up archetable...\n"); 364 LOG (llevDebug, " Setting up archetable...\n");
376 365
377 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 366 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
378 add_arch (at); 367 add_arch (at);
397 */ 386 */
398 387
399void 388void
400dump_all_archetypes (void) 389dump_all_archetypes (void)
401{ 390{
402 archetype * 391 archetype *at;
403 at;
404 392
405 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 393 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
406 { 394 {
407 dump_arch (at); 395 dump_arch (at);
408 fprintf (logfile, "%s\n", errmsg); 396 fprintf (logfile, "%s\n", errmsg);
410} 398}
411 399
412void 400void
413free_all_archs (void) 401free_all_archs (void)
414{ 402{
415 archetype * 403 archetype *at, *next;
416 at, *
417 next;
418 int
419 i = 0, f = 0; 404 int i = 0, f = 0;
420 405
421 for (at = first_archetype; at != NULL; at = next) 406 for (at = first_archetype; at != NULL; at = next)
422 { 407 {
423 if (at->more) 408 if (at->more)
424 next = at->more; 409 next = at->more;
425 else 410 else
426 next = at->next; 411 next = at->next;
427 412
428 delete at; 413 delete
414 at;
415
429 i++; 416 i++;
430 } 417 }
431 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 418 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
432} 419}
433 420
447 * of archetype-structures. 434 * of archetype-structures.
448 */ 435 */
449void 436void
450first_arch_pass (object_thawer & fp) 437first_arch_pass (object_thawer & fp)
451{ 438{
452 archetype *
453 at, *
454 head = NULL, *last_more = NULL; 439 archetype *at, *head = NULL, *last_more = NULL;
455 440
456 at->clone.arch = first_archetype = at = new archetype; 441 at->clone.arch = first_archetype = at = new archetype;
457 442
458 while (int i = load_object (fp, &at->clone, 0)) 443 while (int i = load_object (fp, &at->clone, 0))
459 { 444 {
517 at = new archetype; 502 at = new archetype;
518 503
519 at->clone.arch = at; 504 at->clone.arch = at;
520 } 505 }
521 506
522 delete 507 delete at;
523 at;
524} 508}
525 509
526/* 510/*
527 * Reads the archetype file once more, and links all pointers between 511 * Reads the archetype file once more, and links all pointers between
528 * archetypes. 512 * archetypes.
529 */ 513 */
530 514
531void 515void
532second_arch_pass (object_thawer & thawer) 516second_arch_pass (object_thawer & thawer)
533{ 517{
534 char
535 buf[MAX_BUF], *
536 variable = buf, *argument, *cp; 518 char buf[MAX_BUF], *variable = buf, *argument, *cp;
537 archetype *
538 at = NULL, *other; 519 archetype *at = NULL, *other;
539 520
540 while (fgets (buf, MAX_BUF, thawer) != NULL) 521 while (fgets (buf, MAX_BUF, thawer) != NULL)
541 { 522 {
542 if (*buf == '#') 523 if (*buf == '#')
543 continue; 524 continue;
551 cp--; 532 cp--;
552 } 533 }
553 } 534 }
554 if (!strcmp ("Object", variable)) 535 if (!strcmp ("Object", variable))
555 { 536 {
556 if ((at = find_archetype (argument)) == NULL) 537 if ((at = archetype::find (argument)) == NULL)
557 LOG (llevError, "Warning: failed to find arch %s\n", argument); 538 LOG (llevError, "Warning: failed to find arch %s\n", argument);
558 } 539 }
559 else if (!strcmp ("other_arch", variable)) 540 else if (!strcmp ("other_arch", variable))
560 { 541 {
561 if (at != NULL && at->clone.other_arch == NULL) 542 if (at != NULL && at->clone.other_arch == NULL)
562 { 543 {
563 if ((other = find_archetype (argument)) == NULL) 544 if ((other = archetype::find (argument)) == NULL)
564 LOG (llevError, "Warning: failed to find other_arch %s\n", argument); 545 LOG (llevError, "Warning: failed to find other_arch %s\n", argument);
565 else if (at != NULL) 546 else if (at != NULL)
566 at->clone.other_arch = other; 547 at->clone.other_arch = other;
567 } 548 }
568 } 549 }
584 565
585#ifdef DEBUG 566#ifdef DEBUG
586void 567void
587check_generators (void) 568check_generators (void)
588{ 569{
589 archetype * 570 archetype *at;
590 at;
591 571
592 for (at = first_archetype; at != NULL; at = at->next) 572 for (at = first_archetype; at != NULL; at = at->next)
593 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL) 573 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL)
594 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name); 574 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
595} 575}
603 */ 583 */
604 584
605void 585void
606load_archetypes (void) 586load_archetypes (void)
607{ 587{
608 char
609 filename[MAX_BUF]; 588 char filename[MAX_BUF];
610 589
611#if TIME_ARCH_LOAD 590#if TIME_ARCH_LOAD
612 struct timeval 591 struct timeval
613 tv1, 592 tv1,
614 tv2; 593 tv2;
616 595
617 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 596 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
618 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 597 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
619 598
620 { 599 {
600 object_thawer
621 object_thawer thawer (filename); 601 thawer (filename);
622 602
623 clear_archetable (); 603 clear_archetable ();
624 LOG (llevDebug, " arch-pass 1...\n"); 604 LOG (llevDebug, " arch-pass 1...\n");
625 first_arch_pass (thawer); 605 first_arch_pass (thawer);
626 LOG (llevDebug, " done\n"); 606 LOG (llevDebug, " done\n");
628 608
629 init_archetable (); 609 init_archetable ();
630 warn_archetypes = 1; 610 warn_archetypes = 1;
631 611
632 { 612 {
613 object_thawer
633 object_thawer thawer (filename); 614 thawer (filename);
634 615
635 LOG (llevDebug, " loading treasure...\n"); 616 LOG (llevDebug, " loading treasure...\n");
636 load_treasures (); 617 load_treasures ();
637 LOG (llevDebug, " done\n arch-pass 2...\n"); 618 LOG (llevDebug, " done\n arch-pass 2...\n");
638 second_arch_pass (thawer); 619 second_arch_pass (thawer);
650 */ 631 */
651 632
652object * 633object *
653arch_to_object (archetype *at) 634arch_to_object (archetype *at)
654{ 635{
655 object * 636 object *op;
656 op;
657 637
658 if (at == NULL) 638 if (at == NULL)
659 { 639 {
660 if (warn_archetypes) 640 if (warn_archetypes)
661 LOG (llevError, "Couldn't find archetype.\n"); 641 LOG (llevError, "Couldn't find archetype.\n");
678 */ 658 */
679 659
680object * 660object *
681create_singularity (const char *name) 661create_singularity (const char *name)
682{ 662{
683 object * 663 object *op;
684 op;
685 char
686 buf[MAX_BUF]; 664 char buf[MAX_BUF];
687 665
688 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 666 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
689 op = get_object (); 667 op = get_object ();
690 op->name = op->name_pl = buf; 668 op->name = op->name_pl = buf;
691 SET_FLAG (op, FLAG_NO_PICK); 669 SET_FLAG (op, FLAG_NO_PICK);
698 */ 676 */
699 677
700object * 678object *
701get_archetype (const char *name) 679get_archetype (const char *name)
702{ 680{
703 archetype * 681 archetype *at = archetype::find (name);
704 at;
705 682
706 at = find_archetype (name); 683 if (!at)
707 if (at == NULL)
708 return create_singularity (name); 684 return create_singularity (name);
709 685
710 return arch_to_object (at); 686 return arch_to_object (at);
711} 687}
712 688
715 */ 691 */
716 692
717unsigned long 693unsigned long
718hasharch (const char *str, int tablesize) 694hasharch (const char *str, int tablesize)
719{ 695{
720 unsigned long 696 unsigned long hash = 0;
721 hash = 0;
722 unsigned int 697 unsigned int i = 0;
723 i = 0;
724 const char * 698 const char *p;
725 p;
726 699
727 /* use the one-at-a-time hash function, which supposedly is 700 /* use the one-at-a-time hash function, which supposedly is
728 * better than the djb2-like one used by perl5.005, but 701 * better than the djb2-like one used by perl5.005, but
729 * certainly is better then the bug used here before. 702 * certainly is better then the bug used here before.
730 * see http://burtleburtle.net/bob/hash/doobs.html 703 * see http://burtleburtle.net/bob/hash/doobs.html
747 * Finds, using the hashtable, which archetype matches the given name. 720 * Finds, using the hashtable, which archetype matches the given name.
748 * returns a pointer to the found archetype, otherwise NULL. 721 * returns a pointer to the found archetype, otherwise NULL.
749 */ 722 */
750 723
751archetype * 724archetype *
752find_archetype (const char *name) 725archetype::find (const char *name)
753{ 726{
754#if USE_UNORDERED_MAP
755 name = shstr::find (name);
756
757 if (!name) 727 if (!name)
758 return 0; 728 return 0;
759 729
760 HT::const_iterator i = ht.find ((size_t) name); 730#if USE_UNORDERED_MAP
731 AUTODECL (i, ht.find ((size_t) name));
761 732
762 if (i == ht.end ()) 733 if (i == ht.end ())
763 return 0; 734 return 0;
764 else 735 else
765 return i->second; 736 return i->second;
766#endif 737#endif
767 738
768 archetype * 739 archetype *at;
769 at;
770 unsigned long 740 unsigned long index;
771 index;
772
773 if (name == NULL)
774 return (archetype *) NULL;
775 741
776 index = hasharch (name, ARCHTABLE); 742 index = hasharch (name, ARCHTABLE);
777 arch_search++; 743 arch_search++;
778 for (;;) 744 for (;;)
779 { 745 {
780 at = arch_table[index]; 746 at = arch_table[index];
747
781 if (at == NULL) 748 if (at == NULL)
782 { 749 {
783 if (warn_archetypes) 750 if (warn_archetypes)
784 LOG (llevError, "Couldn't find archetype %s\n", name); 751 LOG (llevError, "Couldn't find archetype %s\n", name);
752
785 return NULL; 753 return NULL;
786 } 754 }
755
787 arch_cmp++; 756 arch_cmp++;
757
788 if (!strcmp ((const char *) at->name, name)) 758 if (!strcmp ((const char *) at->name, name))
789 return at; 759 return at;
760
790 if (++index >= ARCHTABLE) 761 if (++index >= ARCHTABLE)
791 index = 0; 762 index = 0;
792 } 763 }
793} 764}
794 765
801{ 772{
802#if USE_UNORDERED_MAP 773#if USE_UNORDERED_MAP
803 ht.insert (std::make_pair ((size_t) (const char *) at->name, at)); 774 ht.insert (std::make_pair ((size_t) (const char *) at->name, at));
804#endif 775#endif
805 776
806 int
807 index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 777 int index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index;
808 778
809 for (;;) 779 for (;;)
810 { 780 {
811 if (arch_table[index] == NULL) 781 if (arch_table[index] == NULL)
812 { 782 {
828 */ 798 */
829 799
830archetype * 800archetype *
831type_to_archetype (int type) 801type_to_archetype (int type)
832{ 802{
833 archetype * 803 archetype *at;
834 at;
835 804
836 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 805 for (at = first_archetype; at; at = at->more == 0 ? at->next : at->more)
837 if (at->clone.type == type) 806 if (at->clone.type == type)
838 return at; 807 return at;
808
839 return NULL; 809 return 0;
840} 810}
841 811
842/* 812/*
843 * Returns a new object copied from the first archetype matching 813 * Returns a new object copied from the first archetype matching
844 * the given type. 814 * the given type.
846 */ 816 */
847 817
848object * 818object *
849clone_arch (int type) 819clone_arch (int type)
850{ 820{
851 archetype * 821 archetype *at;
852 at;
853 object *
854 op = get_object (); 822 object *op = get_object ();
855 823
856 if ((at = type_to_archetype (type)) == NULL) 824 if ((at = type_to_archetype (type)) == NULL)
857 { 825 {
858 LOG (llevError, "Can't clone archetype %d\n", type); 826 LOG (llevError, "Can't clone archetype %d\n", type);
859 free_object (op); 827 free_object (op);
860 return NULL; 828 return NULL;
861 } 829 }
830
862 copy_object (&at->clone, op); 831 copy_object (&at->clone, op);
863 op->instantiate (); 832 op->instantiate ();
864 return op; 833 return op;
865} 834}
866 835
869 */ 838 */
870 839
871object * 840object *
872object_create_arch (archetype *at) 841object_create_arch (archetype *at)
873{ 842{
874 object * 843 object *op, *prev = 0, *head = 0;
875 op, *
876 prev = NULL, *head = NULL;
877 844
878 while (at) 845 while (at)
879 { 846 {
880 op = arch_to_object (at); 847 op = arch_to_object (at);
881 op->x = at->clone.x; 848 op->x = at->clone.x;
882 op->y = at->clone.y; 849 op->y = at->clone.y;
850
883 if (head) 851 if (head)
884 op->head = head, prev->more = op; 852 op->head = head, prev->more = op;
853
885 if (!head) 854 if (!head)
886 head = op; 855 head = op;
856
887 prev = op; 857 prev = op;
888 at = at->more; 858 at = at->more;
889 } 859 }
860
890 return (head); 861 return (head);
891} 862}
892 863
893/*** end of arch.c ***/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines