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.32 by root, Mon Dec 25 11:25:49 2006 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").
206 * Last, make a check on the full name. 206 * Last, make a check on the full name.
207 */ 207 */
208int 208int
209item_matched_string (object *pl, object *op, const char *name) 209item_matched_string (object *pl, object *op, const char *name)
210{ 210{
211 char *
212 cp,
213 local_name[MAX_BUF]; 211 char *cp, local_name[MAX_BUF];
214 int 212 int count, retval = 0;
215 count,
216 retval = 0;
217 213
218 strcpy (local_name, name); /* strtok is destructive to name */ 214 strcpy (local_name, name); /* strtok is destructive to name */
219 215
220 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ",")) 216 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ","))
221 { 217 {
273 retval = 15; 269 retval = 15;
274 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp))) 270 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp)))
275 retval = 14; 271 retval = 14;
276 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp))) 272 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp)))
277 retval = 14; 273 retval = 14;
278
279 /* Do substring checks, so things like 'Str+1' will match. 274 /* Do substring checks, so things like 'Str+1' will match.
280 * retval of these should perhaps be lower - they are lower 275 * retval of these should perhaps be lower - they are lower
281 * then the specific strcasecmp aboves, but still higher than 276 * then the specific strcasecmp aboves, but still higher than
282 * some other match criteria. 277 * some other match criteria.
283 */ 278 */
285 retval = 12; 280 retval = 12;
286 else if (strstr (query_base_name (op, 0), cp)) 281 else if (strstr (query_base_name (op, 0), cp))
287 retval = 12; 282 retval = 12;
288 else if (strstr (query_short_name (op), cp)) 283 else if (strstr (query_short_name (op), cp))
289 retval = 12; 284 retval = 12;
290
291 /* Check against plural/non plural based on count. */ 285 /* Check against plural/non plural based on count. */
292 else if (count > 1 && !strcasecmp (cp, op->name_pl)) 286 else if (count > 1 && !strcasecmp (cp, op->name_pl))
293 {
294 retval = 6; 287 retval = 6;
295 }
296 else if (count == 1 && !strcasecmp (op->name, cp)) 288 else if (count == 1 && !strcasecmp (op->name, cp))
297 {
298 retval = 6; 289 retval = 6;
299 }
300 /* base name matched - not bad */ 290 /* base name matched - not bad */
301 else if (strcasecmp (cp, op->name) == 0 && !count) 291 else if (strcasecmp (cp, op->name) == 0 && !count)
302 retval = 4; 292 retval = 4;
303 /* Check for partial custom name, but give a real low priority */ 293 /* Check for partial custom name, but give a real low priority */
304 else if (op->custom_name && strstr (op->custom_name, cp)) 294 else if (op->custom_name && strstr (op->custom_name, cp))
306 296
307 if (retval) 297 if (retval)
308 { 298 {
309 if (pl->type == PLAYER) 299 if (pl->type == PLAYER)
310 pl->contr->count = count; 300 pl->contr->count = count;
301
311 return retval; 302 return retval;
312 } 303 }
313 } 304 }
305
314 return 0; 306 return 0;
315} 307}
316 308
317/* 309/*
318 * Initialises the internal linked list of archetypes (read from file). 310 * Initialises the internal linked list of archetypes (read from file).
361 */ 353 */
362 354
363void 355void
364init_archetable (void) 356init_archetable (void)
365{ 357{
366 archetype * 358 archetype *at;
367 at;
368 359
369 LOG (llevDebug, " Setting up archetable...\n"); 360 LOG (llevDebug, " Setting up archetable...\n");
370 361
371 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)
372 add_arch (at); 363 at->hash_add ();
373 364
374 LOG (llevDebug, "done\n"); 365 LOG (llevDebug, "done\n");
375} 366}
376 367
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 368void
407free_all_archs (void) 369free_all_archs (void)
408{ 370{
409 archetype * 371 archetype *at, *next;
410 at, *
411 next;
412 int
413 i = 0, f = 0; 372 int i = 0, f = 0;
414 373
415 for (at = first_archetype; at != NULL; at = next) 374 for (at = first_archetype; at != NULL; at = next)
416 { 375 {
417 if (at->more) 376 if (at->more)
418 next = at->more; 377 next = at->more;
422 delete 381 delete
423 at; 382 at;
424 383
425 i++; 384 i++;
426 } 385 }
386
427 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 387 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
428} 388}
429 389
430archetype::archetype () 390archetype::archetype ()
431{ 391{
432 clear_object (&clone); /* to initial state other also */
433 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_object() */ 392 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_to */
434 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */ 393 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */
435} 394}
436 395
437archetype::~archetype () 396archetype::~archetype ()
438{ 397{
443 * of archetype-structures. 402 * of archetype-structures.
444 */ 403 */
445void 404void
446first_arch_pass (object_thawer & fp) 405first_arch_pass (object_thawer & fp)
447{ 406{
448 archetype * 407 archetype *head = 0, *last_more = 0;
449 at, *
450 head = NULL, *last_more = NULL;
451 408
409 archetype *at = new archetype;
452 at->clone.arch = first_archetype = at = new archetype; 410 at->clone.arch = first_archetype = at;
453 411
454 while (int i = load_object (fp, &at->clone, 0)) 412 while (int i = load_object (fp, &at->clone, 0))
455 { 413 {
456 at->clone.speed_left = (float) (-0.1); 414 at->clone.speed_left = (float) (-0.1);
457 /* copy the body_info to the body_used - this is only really 415 /* copy the body_info to the body_used - this is only really
524 */ 482 */
525 483
526void 484void
527second_arch_pass (object_thawer & thawer) 485second_arch_pass (object_thawer & thawer)
528{ 486{
529 char
530 buf[MAX_BUF], *
531 variable = buf, *argument, *cp; 487 char buf[MAX_BUF], *variable = buf, *argument, *cp;
532 archetype *
533 at = NULL, *other; 488 archetype *at = NULL, *other;
534 489
535 while (fgets (buf, MAX_BUF, thawer) != NULL) 490 while (fgets (buf, MAX_BUF, thawer) != NULL)
536 { 491 {
537 if (*buf == '#') 492 if (*buf == '#')
538 continue; 493 continue;
563 } 518 }
564 else if (!strcmp ("randomitems", variable)) 519 else if (!strcmp ("randomitems", variable))
565 { 520 {
566 if (at != NULL) 521 if (at != NULL)
567 { 522 {
568 treasurelist *
569 tl = find_treasurelist (argument); 523 treasurelist *tl = find_treasurelist (argument);
570 524
571 if (tl == NULL) 525 if (tl == NULL)
572 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument); 526 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument);
573 else 527 else
574 at->clone.randomitems = tl; 528 at->clone.randomitems = tl;
579 533
580#ifdef DEBUG 534#ifdef DEBUG
581void 535void
582check_generators (void) 536check_generators (void)
583{ 537{
584 archetype * 538 archetype *at;
585 at;
586 539
587 for (at = first_archetype; at != NULL; at = at->next) 540 for (at = first_archetype; at != NULL; at = at->next)
588 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL) 541 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); 542 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
590} 543}
598 */ 551 */
599 552
600void 553void
601load_archetypes (void) 554load_archetypes (void)
602{ 555{
603 char
604 filename[MAX_BUF]; 556 char filename[MAX_BUF];
605
606#if TIME_ARCH_LOAD
607 struct timeval
608 tv1,
609 tv2;
610#endif
611 557
612 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 558 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
613 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 559 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
614 560
615 { 561 {
643 589
644/* 590/*
645 * Creates and returns a new object which is a copy of the given archetype. 591 * Creates and returns a new object which is a copy of the given archetype.
646 * This function returns NULL on failure. 592 * This function returns NULL on failure.
647 */ 593 */
648
649object * 594object *
650arch_to_object (archetype *at) 595arch_to_object (archetype *at)
651{ 596{
652 object * 597 object *op;
653 op;
654 598
655 if (at == NULL) 599 if (at == NULL)
656 { 600 {
657 if (warn_archetypes) 601 if (warn_archetypes)
658 LOG (llevError, "Couldn't find archetype.\n"); 602 LOG (llevError, "Couldn't find archetype.\n");
659 603
660 return NULL; 604 return NULL;
661 } 605 }
662 606
663 op = get_object (); 607 op = at->clone.clone ();
664 copy_object (&at->clone, op);
665 op->arch = at; 608 op->arch = at;
666 op->instantiate (); 609 op->instantiate ();
667 return op; 610 return op;
668} 611}
669 612
671 * Creates an object. This function is called by get_archetype() 614 * Creates an object. This function is called by get_archetype()
672 * if it fails to find the appropriate archetype. 615 * if it fails to find the appropriate archetype.
673 * Thus get_archetype() will be guaranteed to always return 616 * Thus get_archetype() will be guaranteed to always return
674 * an object, and never NULL. 617 * an object, and never NULL.
675 */ 618 */
676
677object * 619object *
678create_singularity (const char *name) 620create_singularity (const char *name)
679{ 621{
680 object * op; 622 object *op;
681 char buf[MAX_BUF]; 623 char buf[MAX_BUF];
682 624
683 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 625 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
684 op = get_object (); 626 op = object::create ();
685 op->name = op->name_pl = buf; 627 op->name = op->name_pl = buf;
686 SET_FLAG (op, FLAG_NO_PICK); 628 SET_FLAG (op, FLAG_NO_PICK);
687 return op; 629 return op;
688} 630}
689 631
781} 723}
782 724
783/* 725/*
784 * Adds an archetype to the hashtable. 726 * Adds an archetype to the hashtable.
785 */ 727 */
786 728void
787static void 729archetype::hash_add ()
788add_arch (archetype *at)
789{ 730{
790#if USE_UNORDERED_MAP 731#if USE_UNORDERED_MAP
791 ht.insert (std::make_pair ((size_t) (const char *) at->name, at)); 732 ht.insert (std::make_pair ((size_t) (const char *) name, this));
792#endif 733#else
793 734
794 int index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 735 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
795 736
796 for (;;) 737 for (;;)
797 { 738 {
798 if (arch_table[index] == NULL) 739 if (!arch_table[index])
799 { 740 {
800 arch_table[index] = at; 741 arch_table[index] = this;
801 return; 742 break;
802 } 743 }
803 744
804 if (++index == ARCHTABLE) 745 if (++index == ARCHTABLE)
805 index = 0; 746 index = 0;
806 747
807 if (index == org_index) 748 if (index == org_index)
808 fatal (ARCHTABLE_TOO_SMALL); 749 fatal (ARCHTABLE_TOO_SMALL);
809 } 750 }
751#endif
752}
753
754void
755archetype::hash_del ()
756{
757#if USE_UNORDERED_MAP
758# error remove this from HT
759#else
760
761 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
762
763 for (;;)
764 {
765 if (arch_table[index] == this)
766 {
767 arch_table[index] = 0;
768 break;
769 }
770
771 if (++index == ARCHTABLE)
772 index = 0;
773
774 if (index == org_index)
775 break;
776 }
777#endif
810} 778}
811 779
812/* 780/*
813 * Returns the first archetype using the given type. 781 * Returns the first archetype using the given type.
814 * Used in treasure-generation. 782 * Used in treasure-generation.
834 802
835object * 803object *
836clone_arch (int type) 804clone_arch (int type)
837{ 805{
838 archetype *at; 806 archetype *at;
839 object *op = get_object ();
840 807
841 if ((at = type_to_archetype (type)) == NULL) 808 if ((at = type_to_archetype (type)) == NULL)
842 { 809 {
843 LOG (llevError, "Can't clone archetype %d\n", type); 810 LOG (llevError, "Can't clone archetype %d\n", type);
844 free_object (op);
845 return NULL; 811 return 0;
846 } 812 }
847 813
848 copy_object (&at->clone, op); 814 object *op = at->clone.clone ();
849 op->instantiate (); 815 op->instantiate ();
850 return op; 816 return op;
851} 817}
852 818
853/* 819/*

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines