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.23 by root, Thu Sep 14 23:13:48 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 {
280 retval = 15; 269 retval = 15;
281 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp))) 270 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp)))
282 retval = 14; 271 retval = 14;
283 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp))) 272 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp)))
284 retval = 14; 273 retval = 14;
285
286 /* Do substring checks, so things like 'Str+1' will match. 274 /* Do substring checks, so things like 'Str+1' will match.
287 * retval of these should perhaps be lower - they are lower 275 * retval of these should perhaps be lower - they are lower
288 * then the specific strcasecmp aboves, but still higher than 276 * then the specific strcasecmp aboves, but still higher than
289 * some other match criteria. 277 * some other match criteria.
290 */ 278 */
292 retval = 12; 280 retval = 12;
293 else if (strstr (query_base_name (op, 0), cp)) 281 else if (strstr (query_base_name (op, 0), cp))
294 retval = 12; 282 retval = 12;
295 else if (strstr (query_short_name (op), cp)) 283 else if (strstr (query_short_name (op), cp))
296 retval = 12; 284 retval = 12;
297
298 /* Check against plural/non plural based on count. */ 285 /* Check against plural/non plural based on count. */
299 else if (count > 1 && !strcasecmp (cp, op->name_pl)) 286 else if (count > 1 && !strcasecmp (cp, op->name_pl))
300 {
301 retval = 6; 287 retval = 6;
302 }
303 else if (count == 1 && !strcasecmp (op->name, cp)) 288 else if (count == 1 && !strcasecmp (op->name, cp))
304 {
305 retval = 6; 289 retval = 6;
306 }
307 /* base name matched - not bad */ 290 /* base name matched - not bad */
308 else if (strcasecmp (cp, op->name) == 0 && !count) 291 else if (strcasecmp (cp, op->name) == 0 && !count)
309 retval = 4; 292 retval = 4;
310 /* Check for partial custom name, but give a real low priority */ 293 /* Check for partial custom name, but give a real low priority */
311 else if (op->custom_name && strstr (op->custom_name, cp)) 294 else if (op->custom_name && strstr (op->custom_name, cp))
313 296
314 if (retval) 297 if (retval)
315 { 298 {
316 if (pl->type == PLAYER) 299 if (pl->type == PLAYER)
317 pl->contr->count = count; 300 pl->contr->count = count;
301
318 return retval; 302 return retval;
319 } 303 }
320 } 304 }
305
321 return 0; 306 return 0;
322} 307}
323 308
324/* 309/*
325 * Initialises the internal linked list of archetypes (read from file). 310 * Initialises the internal linked list of archetypes (read from file).
330void 315void
331init_archetypes (void) 316init_archetypes (void)
332{ /* called from add_player() and edit() */ 317{ /* called from add_player() and edit() */
333 if (first_archetype != NULL) /* Only do this once */ 318 if (first_archetype != NULL) /* Only do this once */
334 return; 319 return;
320
335 arch_init = 1; 321 arch_init = 1;
336 load_archetypes (); 322 load_archetypes ();
337 arch_init = 0; 323 arch_init = 0;
338 empty_archetype = find_archetype ("empty_archetype"); 324 empty_archetype = archetype::find ("empty_archetype");
339 325
340/* init_blocksview();*/ 326/* init_blocksview();*/
341} 327}
342 328
343/* 329/*
367 */ 353 */
368 354
369void 355void
370init_archetable (void) 356init_archetable (void)
371{ 357{
372 archetype * 358 archetype *at;
373 at;
374 359
375 LOG (llevDebug, " Setting up archetable...\n"); 360 LOG (llevDebug, " Setting up archetable...\n");
376 361
377 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 362 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
378 add_arch (at); 363 add_arch (at);
397 */ 382 */
398 383
399void 384void
400dump_all_archetypes (void) 385dump_all_archetypes (void)
401{ 386{
402 archetype * 387 archetype *at;
403 at;
404 388
405 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 389 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
406 { 390 {
407 dump_arch (at); 391 dump_arch (at);
408 fprintf (logfile, "%s\n", errmsg); 392 fprintf (logfile, "%s\n", errmsg);
410} 394}
411 395
412void 396void
413free_all_archs (void) 397free_all_archs (void)
414{ 398{
415 archetype * 399 archetype *at, *next;
416 at, *
417 next;
418 int
419 i = 0, f = 0; 400 int i = 0, f = 0;
420 401
421 for (at = first_archetype; at != NULL; at = next) 402 for (at = first_archetype; at != NULL; at = next)
422 { 403 {
423 if (at->more) 404 if (at->more)
424 next = at->more; 405 next = at->more;
425 else 406 else
426 next = at->next; 407 next = at->next;
427 408
428 delete at; 409 delete
410 at;
411
429 i++; 412 i++;
430 } 413 }
431 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 414 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
432} 415}
433 416
447 * of archetype-structures. 430 * of archetype-structures.
448 */ 431 */
449void 432void
450first_arch_pass (object_thawer & fp) 433first_arch_pass (object_thawer & fp)
451{ 434{
452 archetype *
453 at, *
454 head = NULL, *last_more = NULL; 435 archetype *at, *head = NULL, *last_more = NULL;
455 436
456 at->clone.arch = first_archetype = at = new archetype; 437 at->clone.arch = first_archetype = at = new archetype;
457 438
458 while (int i = load_object (fp, &at->clone, 0)) 439 while (int i = load_object (fp, &at->clone, 0))
459 { 440 {
517 at = new archetype; 498 at = new archetype;
518 499
519 at->clone.arch = at; 500 at->clone.arch = at;
520 } 501 }
521 502
522 delete 503 delete at;
523 at;
524} 504}
525 505
526/* 506/*
527 * Reads the archetype file once more, and links all pointers between 507 * Reads the archetype file once more, and links all pointers between
528 * archetypes. 508 * archetypes.
529 */ 509 */
530 510
531void 511void
532second_arch_pass (object_thawer & thawer) 512second_arch_pass (object_thawer & thawer)
533{ 513{
534 char
535 buf[MAX_BUF], *
536 variable = buf, *argument, *cp; 514 char buf[MAX_BUF], *variable = buf, *argument, *cp;
537 archetype *
538 at = NULL, *other; 515 archetype *at = NULL, *other;
539 516
540 while (fgets (buf, MAX_BUF, thawer) != NULL) 517 while (fgets (buf, MAX_BUF, thawer) != NULL)
541 { 518 {
542 if (*buf == '#') 519 if (*buf == '#')
543 continue; 520 continue;
551 cp--; 528 cp--;
552 } 529 }
553 } 530 }
554 if (!strcmp ("Object", variable)) 531 if (!strcmp ("Object", variable))
555 { 532 {
556 if ((at = find_archetype (argument)) == NULL) 533 if ((at = archetype::find (argument)) == NULL)
557 LOG (llevError, "Warning: failed to find arch %s\n", argument); 534 LOG (llevError, "Warning: failed to find arch %s\n", argument);
558 } 535 }
559 else if (!strcmp ("other_arch", variable)) 536 else if (!strcmp ("other_arch", variable))
560 { 537 {
561 if (at != NULL && at->clone.other_arch == NULL) 538 if (at != NULL && at->clone.other_arch == NULL)
562 { 539 {
563 if ((other = find_archetype (argument)) == NULL) 540 if ((other = archetype::find (argument)) == NULL)
564 LOG (llevError, "Warning: failed to find other_arch %s\n", argument); 541 LOG (llevError, "Warning: failed to find other_arch %s\n", argument);
565 else if (at != NULL) 542 else if (at != NULL)
566 at->clone.other_arch = other; 543 at->clone.other_arch = other;
567 } 544 }
568 } 545 }
584 561
585#ifdef DEBUG 562#ifdef DEBUG
586void 563void
587check_generators (void) 564check_generators (void)
588{ 565{
589 archetype * 566 archetype *at;
590 at;
591 567
592 for (at = first_archetype; at != NULL; at = at->next) 568 for (at = first_archetype; at != NULL; at = at->next)
593 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL) 569 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); 570 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
595} 571}
603 */ 579 */
604 580
605void 581void
606load_archetypes (void) 582load_archetypes (void)
607{ 583{
608 char
609 filename[MAX_BUF]; 584 char filename[MAX_BUF];
610 585
611#if TIME_ARCH_LOAD 586#if TIME_ARCH_LOAD
612 struct timeval 587 struct timeval
613 tv1, 588 tv1,
614 tv2; 589 tv2;
616 591
617 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 592 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
618 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 593 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
619 594
620 { 595 {
596 object_thawer
621 object_thawer thawer (filename); 597 thawer (filename);
622 598
623 clear_archetable (); 599 clear_archetable ();
624 LOG (llevDebug, " arch-pass 1...\n"); 600 LOG (llevDebug, " arch-pass 1...\n");
625 first_arch_pass (thawer); 601 first_arch_pass (thawer);
626 LOG (llevDebug, " done\n"); 602 LOG (llevDebug, " done\n");
628 604
629 init_archetable (); 605 init_archetable ();
630 warn_archetypes = 1; 606 warn_archetypes = 1;
631 607
632 { 608 {
609 object_thawer
633 object_thawer thawer (filename); 610 thawer (filename);
634 611
635 LOG (llevDebug, " loading treasure...\n"); 612 LOG (llevDebug, " loading treasure...\n");
636 load_treasures (); 613 load_treasures ();
637 LOG (llevDebug, " done\n arch-pass 2...\n"); 614 LOG (llevDebug, " done\n arch-pass 2...\n");
638 second_arch_pass (thawer); 615 second_arch_pass (thawer);
650 */ 627 */
651 628
652object * 629object *
653arch_to_object (archetype *at) 630arch_to_object (archetype *at)
654{ 631{
655 object * 632 object *op;
656 op;
657 633
658 if (at == NULL) 634 if (at == NULL)
659 { 635 {
660 if (warn_archetypes) 636 if (warn_archetypes)
661 LOG (llevError, "Couldn't find archetype.\n"); 637 LOG (llevError, "Couldn't find archetype.\n");
678 */ 654 */
679 655
680object * 656object *
681create_singularity (const char *name) 657create_singularity (const char *name)
682{ 658{
683 object * 659 object *op;
684 op;
685 char
686 buf[MAX_BUF]; 660 char buf[MAX_BUF];
687 661
688 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 662 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
689 op = get_object (); 663 op = get_object ();
690 op->name = op->name_pl = buf; 664 op->name = op->name_pl = buf;
691 SET_FLAG (op, FLAG_NO_PICK); 665 SET_FLAG (op, FLAG_NO_PICK);
698 */ 672 */
699 673
700object * 674object *
701get_archetype (const char *name) 675get_archetype (const char *name)
702{ 676{
703 archetype * 677 archetype *at = archetype::find (name);
704 at;
705 678
706 at = find_archetype (name); 679 if (!at)
707 if (at == NULL)
708 return create_singularity (name); 680 return create_singularity (name);
709 681
710 return arch_to_object (at); 682 return arch_to_object (at);
711} 683}
712 684
715 */ 687 */
716 688
717unsigned long 689unsigned long
718hasharch (const char *str, int tablesize) 690hasharch (const char *str, int tablesize)
719{ 691{
720 unsigned long 692 unsigned long hash = 0;
721 hash = 0;
722 unsigned int 693 unsigned int i = 0;
723 i = 0;
724 const char * 694 const char *p;
725 p;
726 695
727 /* use the one-at-a-time hash function, which supposedly is 696 /* use the one-at-a-time hash function, which supposedly is
728 * better than the djb2-like one used by perl5.005, but 697 * better than the djb2-like one used by perl5.005, but
729 * certainly is better then the bug used here before. 698 * certainly is better then the bug used here before.
730 * see http://burtleburtle.net/bob/hash/doobs.html 699 * see http://burtleburtle.net/bob/hash/doobs.html
747 * Finds, using the hashtable, which archetype matches the given name. 716 * Finds, using the hashtable, which archetype matches the given name.
748 * returns a pointer to the found archetype, otherwise NULL. 717 * returns a pointer to the found archetype, otherwise NULL.
749 */ 718 */
750 719
751archetype * 720archetype *
752find_archetype (const char *name) 721archetype::find (const char *name)
753{ 722{
754#if USE_UNORDERED_MAP
755 name = shstr::find (name);
756
757 if (!name) 723 if (!name)
758 return 0; 724 return 0;
759 725
760 HT::const_iterator i = ht.find ((size_t) name); 726#if USE_UNORDERED_MAP
727 AUTODECL (i, ht.find ((size_t) name));
761 728
762 if (i == ht.end ()) 729 if (i == ht.end ())
763 return 0; 730 return 0;
764 else 731 else
765 return i->second; 732 return i->second;
766#endif 733#endif
767 734
768 archetype * 735 archetype *at;
769 at;
770 unsigned long 736 unsigned long index;
771 index;
772
773 if (name == NULL)
774 return (archetype *) NULL;
775 737
776 index = hasharch (name, ARCHTABLE); 738 index = hasharch (name, ARCHTABLE);
777 arch_search++; 739 arch_search++;
778 for (;;) 740 for (;;)
779 { 741 {
780 at = arch_table[index]; 742 at = arch_table[index];
743
781 if (at == NULL) 744 if (at == NULL)
782 { 745 {
783 if (warn_archetypes) 746 if (warn_archetypes)
784 LOG (llevError, "Couldn't find archetype %s\n", name); 747 LOG (llevError, "Couldn't find archetype %s\n", name);
748
785 return NULL; 749 return NULL;
786 } 750 }
751
787 arch_cmp++; 752 arch_cmp++;
753
788 if (!strcmp ((const char *) at->name, name)) 754 if (!strcmp ((const char *) at->name, name))
789 return at; 755 return at;
756
790 if (++index >= ARCHTABLE) 757 if (++index >= ARCHTABLE)
791 index = 0; 758 index = 0;
792 } 759 }
793} 760}
794 761
801{ 768{
802#if USE_UNORDERED_MAP 769#if USE_UNORDERED_MAP
803 ht.insert (std::make_pair ((size_t) (const char *) at->name, at)); 770 ht.insert (std::make_pair ((size_t) (const char *) at->name, at));
804#endif 771#endif
805 772
806 int
807 index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 773 int index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index;
808 774
809 for (;;) 775 for (;;)
810 { 776 {
811 if (arch_table[index] == NULL) 777 if (arch_table[index] == NULL)
812 { 778 {
828 */ 794 */
829 795
830archetype * 796archetype *
831type_to_archetype (int type) 797type_to_archetype (int type)
832{ 798{
833 archetype * 799 archetype *at;
834 at;
835 800
836 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 801 for (at = first_archetype; at; at = at->more == 0 ? at->next : at->more)
837 if (at->clone.type == type) 802 if (at->clone.type == type)
838 return at; 803 return at;
804
839 return NULL; 805 return 0;
840} 806}
841 807
842/* 808/*
843 * Returns a new object copied from the first archetype matching 809 * Returns a new object copied from the first archetype matching
844 * the given type. 810 * the given type.
846 */ 812 */
847 813
848object * 814object *
849clone_arch (int type) 815clone_arch (int type)
850{ 816{
851 archetype * 817 archetype *at;
852 at;
853 object *
854 op = get_object (); 818 object *op = get_object ();
855 819
856 if ((at = type_to_archetype (type)) == NULL) 820 if ((at = type_to_archetype (type)) == NULL)
857 { 821 {
858 LOG (llevError, "Can't clone archetype %d\n", type); 822 LOG (llevError, "Can't clone archetype %d\n", type);
859 free_object (op); 823 free_object (op);
860 return NULL; 824 return NULL;
861 } 825 }
826
862 copy_object (&at->clone, op); 827 copy_object (&at->clone, op);
863 op->instantiate (); 828 op->instantiate ();
864 return op; 829 return op;
865} 830}
866 831
869 */ 834 */
870 835
871object * 836object *
872object_create_arch (archetype *at) 837object_create_arch (archetype *at)
873{ 838{
874 object * 839 object *op, *prev = 0, *head = 0;
875 op, *
876 prev = NULL, *head = NULL;
877 840
878 while (at) 841 while (at)
879 { 842 {
880 op = arch_to_object (at); 843 op = arch_to_object (at);
881 op->x = at->clone.x; 844 op->x = at->clone.x;
882 op->y = at->clone.y; 845 op->y = at->clone.y;
846
883 if (head) 847 if (head)
884 op->head = head, prev->more = op; 848 op->head = head, prev->more = op;
849
885 if (!head) 850 if (!head)
886 head = op; 851 head = op;
852
887 prev = op; 853 prev = op;
888 at = at->more; 854 at = at->more;
889 } 855 }
856
890 return (head); 857 return (head);
891} 858}
892 859
893/*** end of arch.c ***/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines