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.20 by root, Thu Sep 14 21:16:11 2006 UTC vs.
Revision 1.35 by root, Wed Jan 3 20:32:13 2007 UTC

16 16
17 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
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 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>
22*/ 22*/
23 23
24#include <cassert> 24#include <cassert>
25 25
26#include <tr1/unordered_map>
27
28#include <global.h> 26#include <global.h>
29#include <arch.h>
30#include <funcpoint.h> 27#include <funcpoint.h>
31#include <loader.h> 28#include <loader.h>
32 29
33/* IF set, does a little timing on the archetype load. */ 30#define USE_UNORDERED_MAP 0
34#define TIME_ARCH_LOAD 0
35 31
36static void add_arch (archetype *at); 32#if USE_UNORDERED_MAP
33# include <tr1/functional>
34# include <tr1/unordered_map>
35#endif
37 36
38static archetype *arch_table[ARCHTABLE];
39int arch_cmp = 0; /* How many strcmp's */ 37int arch_cmp = 0; /* How many strcmp's */
40int arch_search = 0; /* How many searches */ 38int arch_search = 0; /* How many searches */
41int arch_init; /* True if doing arch initialization */ 39int arch_init; /* True if doing arch initialization */
42 40
43/* The naming of these functions is really poor - they are all 41/* The naming of these functions is really poor - they are all
51#if USE_UNORDERED_MAP 49#if USE_UNORDERED_MAP
52// the hashtable 50// the hashtable
53typedef std::tr1::unordered_map 51typedef std::tr1::unordered_map
54 < 52 <
55 std::size_t, 53 std::size_t,
56 archetype *, 54 arch_ptr,
57 std::hash<size_t>, 55 std::tr1::hash<size_t>,
58 std::equal_to<size_t>, 56 std::equal_to<size_t>,
59 slice_allocator< std::pair<const std::size_t, archetype *> > 57 slice_allocator< std::pair<const std::size_t, archetype *> >
60 true, 58 true,
61 > HT; 59 > HT;
62 60
63static HT ht; 61static HT ht;
62#else
63static arch_ptr arch_table[ARCHTABLE];
64#endif 64#endif
65 65
66/** 66/**
67 * GROS - This function retrieves an archetype given the name that appears 67 * GROS - This function retrieves an archetype given the name that appears
68 * during the game (for example, "writing pen" instead of "stylus"). 68 * during the game (for example, "writing pen" instead of "stylus").
118 * If type is -1, ew don't match on type. 118 * If type is -1, ew don't match on type.
119 */ 119 */
120object * 120object *
121get_archetype_by_skill_name (const char *skill, int type) 121get_archetype_by_skill_name (const char *skill, int type)
122{ 122{
123 archetype * 123 archetype *at;
124 at;
125 124
126 if (skill == NULL) 125 if (skill)
127 return NULL;
128
129 for (at = first_archetype; at != NULL; at = at->next) 126 for (at = first_archetype; at; at = at->next)
130 {
131 if (((type == -1) || (type == at->clone.type)) && (!strcmp (at->clone.skill, skill))) 127 if (((type == -1) || (type == at->clone.type)) && (!strcmp (at->clone.skill, skill)))
132 return arch_to_object (at); 128 return arch_to_object (at);
133 } 129
134 return NULL; 130 return 0;
135} 131}
136 132
137/* similiar to above - this returns the first archetype 133/* similiar to above - this returns the first archetype
138 * that matches both the type and subtype. type and subtype 134 * that matches both the type and subtype. type and subtype
139 * can be -1 to say ignore, but in this case, the match it does 135 * can be -1 to say ignore, but in this case, the match it does
179 for (i = strlen (tmpname); i > 0; i--) 175 for (i = strlen (tmpname); i > 0; i--)
180 { 176 {
181 tmpname[i] = 0; 177 tmpname[i] = 0;
182 at = find_archetype_by_object_name (tmpname); 178 at = find_archetype_by_object_name (tmpname);
183 179
184 if (at != NULL) 180 if (at)
185 return arch_to_object (at); 181 return arch_to_object (at);
186 } 182 }
187 183
188 return create_singularity (name); 184 return create_singularity (name);
189} 185}
206 * Last, make a check on the full name. 202 * Last, make a check on the full name.
207 */ 203 */
208int 204int
209item_matched_string (object *pl, object *op, const char *name) 205item_matched_string (object *pl, object *op, const char *name)
210{ 206{
211 char *
212 cp,
213 local_name[MAX_BUF]; 207 char *cp, local_name[MAX_BUF];
214 int 208 int count, retval = 0;
215 count,
216 retval = 0;
217 209
218 strcpy (local_name, name); /* strtok is destructive to name */ 210 strcpy (local_name, name); /* strtok is destructive to name */
219 211
220 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ",")) 212 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ","))
221 { 213 {
273 retval = 15; 265 retval = 15;
274 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp))) 266 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp)))
275 retval = 14; 267 retval = 14;
276 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp))) 268 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp)))
277 retval = 14; 269 retval = 14;
278
279 /* Do substring checks, so things like 'Str+1' will match. 270 /* Do substring checks, so things like 'Str+1' will match.
280 * retval of these should perhaps be lower - they are lower 271 * retval of these should perhaps be lower - they are lower
281 * then the specific strcasecmp aboves, but still higher than 272 * then the specific strcasecmp aboves, but still higher than
282 * some other match criteria. 273 * some other match criteria.
283 */ 274 */
285 retval = 12; 276 retval = 12;
286 else if (strstr (query_base_name (op, 0), cp)) 277 else if (strstr (query_base_name (op, 0), cp))
287 retval = 12; 278 retval = 12;
288 else if (strstr (query_short_name (op), cp)) 279 else if (strstr (query_short_name (op), cp))
289 retval = 12; 280 retval = 12;
290
291 /* Check against plural/non plural based on count. */ 281 /* Check against plural/non plural based on count. */
292 else if (count > 1 && !strcasecmp (cp, op->name_pl)) 282 else if (count > 1 && !strcasecmp (cp, op->name_pl))
293 {
294 retval = 6; 283 retval = 6;
295 }
296 else if (count == 1 && !strcasecmp (op->name, cp)) 284 else if (count == 1 && !strcasecmp (op->name, cp))
297 {
298 retval = 6; 285 retval = 6;
299 }
300 /* base name matched - not bad */ 286 /* base name matched - not bad */
301 else if (strcasecmp (cp, op->name) == 0 && !count) 287 else if (strcasecmp (cp, op->name) == 0 && !count)
302 retval = 4; 288 retval = 4;
303 /* Check for partial custom name, but give a real low priority */ 289 /* Check for partial custom name, but give a real low priority */
304 else if (op->custom_name && strstr (op->custom_name, cp)) 290 else if (op->custom_name && strstr (op->custom_name, cp))
306 292
307 if (retval) 293 if (retval)
308 { 294 {
309 if (pl->type == PLAYER) 295 if (pl->type == PLAYER)
310 pl->contr->count = count; 296 pl->contr->count = count;
297
311 return retval; 298 return retval;
312 } 299 }
313 } 300 }
301
314 return 0; 302 return 0;
315} 303}
316 304
317/* 305/*
318 * Initialises the internal linked list of archetypes (read from file). 306 * Initialises the internal linked list of archetypes (read from file).
361 */ 349 */
362 350
363void 351void
364init_archetable (void) 352init_archetable (void)
365{ 353{
366 archetype * 354 archetype *at;
367 at;
368 355
369 LOG (llevDebug, " Setting up archetable...\n"); 356 LOG (llevDebug, " Setting up archetable...\n");
370 357
371 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 358 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
372 add_arch (at); 359 at->hash_add ();
373 360
374 LOG (llevDebug, "done\n"); 361 LOG (llevDebug, "done\n");
375} 362}
376 363
377/*
378 * Dumps an archetype to debug-level output.
379 */
380
381void
382dump_arch (archetype *at)
383{
384 dump_object (&at->clone);
385}
386
387/*
388 * Dumps _all_ archetypes to debug-level output.
389 * If you run crossfire with debug, and enter DM-mode, you can trigger
390 * this with the O key.
391 */
392
393void
394dump_all_archetypes (void)
395{
396 archetype *
397 at;
398
399 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
400 {
401 dump_arch (at);
402 fprintf (logfile, "%s\n", errmsg);
403 }
404}
405
406void 364void
407free_all_archs (void) 365free_all_archs (void)
408{ 366{
409 archetype * 367 archetype *at, *next;
410 at, *
411 next;
412 int
413 i = 0, f = 0; 368 int i = 0, f = 0;
414 369
415 for (at = first_archetype; at != NULL; at = next) 370 for (at = first_archetype; at != NULL; at = next)
416 { 371 {
417 if (at->more) 372 if (at->more)
418 next = at->more; 373 next = at->more;
422 delete 377 delete
423 at; 378 at;
424 379
425 i++; 380 i++;
426 } 381 }
382
427 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 383 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
428} 384}
429 385
430archetype::archetype () 386archetype::archetype ()
431{ 387{
432 clear_object (&clone); /* to initial state other also */
433 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_object() */ 388 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_to */
434 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */ 389 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */
435} 390}
436 391
437archetype::~archetype () 392archetype::~archetype ()
438{ 393{
443 * of archetype-structures. 398 * of archetype-structures.
444 */ 399 */
445void 400void
446first_arch_pass (object_thawer & fp) 401first_arch_pass (object_thawer & fp)
447{ 402{
448 archetype * 403 archetype *head = 0, *last_more = 0;
449 at, *
450 head = NULL, *last_more = NULL;
451 404
405 archetype *at = new archetype;
452 at->clone.arch = first_archetype = at = new archetype; 406 at->clone.arch = first_archetype = at;
453 407
454 while (int i = load_object (fp, &at->clone, 0)) 408 while (int i = load_object (fp, &at->clone, 0))
455 { 409 {
456 at->clone.speed_left = (float) (-0.1); 410 at->clone.speed_left = (float) (-0.1);
457 /* copy the body_info to the body_used - this is only really 411 /* copy the body_info to the body_used - this is only really
524 */ 478 */
525 479
526void 480void
527second_arch_pass (object_thawer & thawer) 481second_arch_pass (object_thawer & thawer)
528{ 482{
529 char
530 buf[MAX_BUF], *
531 variable = buf, *argument, *cp; 483 char buf[MAX_BUF], *variable = buf, *argument, *cp;
532 archetype *
533 at = NULL, *other; 484 archetype *at = NULL, *other;
534 485
535 while (fgets (buf, MAX_BUF, thawer) != NULL) 486 while (fgets (buf, MAX_BUF, thawer) != NULL)
536 { 487 {
537 if (*buf == '#') 488 if (*buf == '#')
538 continue; 489 continue;
563 } 514 }
564 else if (!strcmp ("randomitems", variable)) 515 else if (!strcmp ("randomitems", variable))
565 { 516 {
566 if (at != NULL) 517 if (at != NULL)
567 { 518 {
568 treasurelist *
569 tl = find_treasurelist (argument); 519 treasurelist *tl = find_treasurelist (argument);
570 520
571 if (tl == NULL) 521 if (tl == NULL)
572 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument); 522 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument);
573 else 523 else
574 at->clone.randomitems = tl; 524 at->clone.randomitems = tl;
579 529
580#ifdef DEBUG 530#ifdef DEBUG
581void 531void
582check_generators (void) 532check_generators (void)
583{ 533{
584 archetype * 534 archetype *at;
585 at;
586 535
587 for (at = first_archetype; at != NULL; at = at->next) 536 for (at = first_archetype; at != NULL; at = at->next)
588 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL) 537 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL)
589 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name); 538 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
590} 539}
598 */ 547 */
599 548
600void 549void
601load_archetypes (void) 550load_archetypes (void)
602{ 551{
603 char
604 filename[MAX_BUF]; 552 char filename[MAX_BUF];
605
606#if TIME_ARCH_LOAD
607 struct timeval
608 tv1,
609 tv2;
610#endif
611 553
612 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 554 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
613 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 555 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
614 556
615 { 557 {
629 object_thawer 571 object_thawer
630 thawer (filename); 572 thawer (filename);
631 573
632 LOG (llevDebug, " loading treasure...\n"); 574 LOG (llevDebug, " loading treasure...\n");
633 load_treasures (); 575 load_treasures ();
576 LOG (llevDebug, " done\n");
634 LOG (llevDebug, " done\n arch-pass 2...\n"); 577 LOG (llevDebug, " arch-pass 2...\n");
635 second_arch_pass (thawer); 578 second_arch_pass (thawer);
636 LOG (llevDebug, " done\n"); 579 LOG (llevDebug, " done\n");
637#ifdef DEBUG 580#ifdef DEBUG
638 check_generators (); 581 check_generators ();
639#endif 582#endif
643 586
644/* 587/*
645 * Creates and returns a new object which is a copy of the given archetype. 588 * Creates and returns a new object which is a copy of the given archetype.
646 * This function returns NULL on failure. 589 * This function returns NULL on failure.
647 */ 590 */
648
649object * 591object *
650arch_to_object (archetype *at) 592arch_to_object (archetype *at)
651{ 593{
652 object * 594 object *op;
653 op;
654 595
655 if (at == NULL) 596 if (at == NULL)
656 { 597 {
657 if (warn_archetypes) 598 if (warn_archetypes)
658 LOG (llevError, "Couldn't find archetype.\n"); 599 LOG (llevError, "Couldn't find archetype.\n");
659 600
660 return NULL; 601 return NULL;
661 } 602 }
662 603
663 op = get_object (); 604 op = at->clone.clone ();
664 copy_object (&at->clone, op);
665 op->arch = at; 605 op->arch = at;
666 op->instantiate (); 606 op->instantiate ();
667 return op; 607 return op;
668} 608}
669 609
671 * Creates an object. This function is called by get_archetype() 611 * Creates an object. This function is called by get_archetype()
672 * if it fails to find the appropriate archetype. 612 * if it fails to find the appropriate archetype.
673 * Thus get_archetype() will be guaranteed to always return 613 * Thus get_archetype() will be guaranteed to always return
674 * an object, and never NULL. 614 * an object, and never NULL.
675 */ 615 */
676
677object * 616object *
678create_singularity (const char *name) 617create_singularity (const char *name)
679{ 618{
680 object * op; 619 object *op;
681 char buf[MAX_BUF]; 620 char buf[MAX_BUF];
682 621
683 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 622 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
684 op = get_object (); 623 op = object::create ();
685 op->name = op->name_pl = buf; 624 op->name = op->name_pl = buf;
686 SET_FLAG (op, FLAG_NO_PICK); 625 SET_FLAG (op, FLAG_NO_PICK);
687 return op; 626 return op;
688} 627}
689 628
690/* 629/*
691 * Finds which archetype matches the given name, and returns a new 630 * Finds which archetype matches the given name, and returns a new
692 * object containing a copy of the archetype. 631 * object containing a copy of the archetype.
693 */ 632 */
694
695object * 633object *
696get_archetype (const char *name) 634get_archetype (const char *name)
697{ 635{
698 archetype *at = archetype::find (name); 636 archetype *at = archetype::find (name);
699 637
781} 719}
782 720
783/* 721/*
784 * Adds an archetype to the hashtable. 722 * Adds an archetype to the hashtable.
785 */ 723 */
786 724void
787static void 725archetype::hash_add ()
788add_arch (archetype *at)
789{ 726{
790#if USE_UNORDERED_MAP 727#if USE_UNORDERED_MAP
791 ht.insert (std::make_pair ((size_t) (const char *) at->name, at)); 728 ht.insert (std::make_pair ((size_t) (const char *) name, this));
792#endif 729#else
793 730
794 int index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 731 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
795 732
796 for (;;) 733 for (;;)
797 { 734 {
798 if (arch_table[index] == NULL) 735 if (!arch_table[index])
799 { 736 {
800 arch_table[index] = at; 737 arch_table[index] = this;
801 return; 738 break;
802 } 739 }
803 740
804 if (++index == ARCHTABLE) 741 if (++index == ARCHTABLE)
805 index = 0; 742 index = 0;
806 743
807 if (index == org_index) 744 if (index == org_index)
808 fatal (ARCHTABLE_TOO_SMALL); 745 fatal (ARCHTABLE_TOO_SMALL);
809 } 746 }
747#endif
748}
749
750void
751archetype::hash_del ()
752{
753#if USE_UNORDERED_MAP
754# error remove this from HT
755#else
756
757 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
758
759 for (;;)
760 {
761 if (arch_table[index] == this)
762 {
763 arch_table[index] = 0;
764 break;
765 }
766
767 if (++index == ARCHTABLE)
768 index = 0;
769
770 if (index == org_index)
771 break;
772 }
773#endif
810} 774}
811 775
812/* 776/*
813 * Returns the first archetype using the given type. 777 * Returns the first archetype using the given type.
814 * Used in treasure-generation. 778 * Used in treasure-generation.
834 798
835object * 799object *
836clone_arch (int type) 800clone_arch (int type)
837{ 801{
838 archetype *at; 802 archetype *at;
839 object *op = get_object ();
840 803
841 if ((at = type_to_archetype (type)) == NULL) 804 if ((at = type_to_archetype (type)) == NULL)
842 { 805 {
843 LOG (llevError, "Can't clone archetype %d\n", type); 806 LOG (llevError, "Can't clone archetype %d\n", type);
844 free_object (op);
845 return NULL; 807 return 0;
846 } 808 }
847 809
848 copy_object (&at->clone, op); 810 object *op = at->clone.clone ();
849 op->instantiate (); 811 op->instantiate ();
850 return op; 812 return op;
851} 813}
852 814
853/* 815/*

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines