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.27 by root, Sat Dec 9 14:01:12 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{
443 * of archetype-structures. 403 * of archetype-structures.
444 */ 404 */
445void 405void
446first_arch_pass (object_thawer & fp) 406first_arch_pass (object_thawer & fp)
447{ 407{
448 archetype * 408 archetype *head = 0, *last_more = 0;
449 at, *
450 head = NULL, *last_more = NULL;
451 409
410 archetype *at = new archetype;
452 at->clone.arch = first_archetype = at = new archetype; 411 at->clone.arch = first_archetype = at;
453 412
454 while (int i = load_object (fp, &at->clone, 0)) 413 while (int i = load_object (fp, &at->clone, 0))
455 { 414 {
456 at->clone.speed_left = (float) (-0.1); 415 at->clone.speed_left = (float) (-0.1);
457 /* copy the body_info to the body_used - this is only really 416 /* copy the body_info to the body_used - this is only really
524 */ 483 */
525 484
526void 485void
527second_arch_pass (object_thawer & thawer) 486second_arch_pass (object_thawer & thawer)
528{ 487{
529 char
530 buf[MAX_BUF], *
531 variable = buf, *argument, *cp; 488 char buf[MAX_BUF], *variable = buf, *argument, *cp;
532 archetype *
533 at = NULL, *other; 489 archetype *at = NULL, *other;
534 490
535 while (fgets (buf, MAX_BUF, thawer) != NULL) 491 while (fgets (buf, MAX_BUF, thawer) != NULL)
536 { 492 {
537 if (*buf == '#') 493 if (*buf == '#')
538 continue; 494 continue;
563 } 519 }
564 else if (!strcmp ("randomitems", variable)) 520 else if (!strcmp ("randomitems", variable))
565 { 521 {
566 if (at != NULL) 522 if (at != NULL)
567 { 523 {
568 treasurelist *
569 tl = find_treasurelist (argument); 524 treasurelist *tl = find_treasurelist (argument);
570 525
571 if (tl == NULL) 526 if (tl == NULL)
572 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument); 527 LOG (llevError, "Failed to link treasure to arch (%s): %s\n", &at->name, argument);
573 else 528 else
574 at->clone.randomitems = tl; 529 at->clone.randomitems = tl;
579 534
580#ifdef DEBUG 535#ifdef DEBUG
581void 536void
582check_generators (void) 537check_generators (void)
583{ 538{
584 archetype * 539 archetype *at;
585 at;
586 540
587 for (at = first_archetype; at != NULL; at = at->next) 541 for (at = first_archetype; at != NULL; at = at->next)
588 if (QUERY_FLAG (&at->clone, FLAG_GENERATOR) && at->clone.other_arch == NULL) 542 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); 543 LOG (llevError, "Warning: %s is generator but lacks other_arch.\n", &at->name);
590} 544}
598 */ 552 */
599 553
600void 554void
601load_archetypes (void) 555load_archetypes (void)
602{ 556{
603 char
604 filename[MAX_BUF]; 557 char filename[MAX_BUF];
605
606#if TIME_ARCH_LOAD
607 struct timeval
608 tv1,
609 tv2;
610#endif
611 558
612 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 559 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
613 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 560 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
614 561
615 { 562 {
647 */ 594 */
648 595
649object * 596object *
650arch_to_object (archetype *at) 597arch_to_object (archetype *at)
651{ 598{
652 object * 599 object *op;
653 op;
654 600
655 if (at == NULL) 601 if (at == NULL)
656 { 602 {
657 if (warn_archetypes) 603 if (warn_archetypes)
658 LOG (llevError, "Couldn't find archetype.\n"); 604 LOG (llevError, "Couldn't find archetype.\n");
675 */ 621 */
676 622
677object * 623object *
678create_singularity (const char *name) 624create_singularity (const char *name)
679{ 625{
680 object * op; 626 object *op;
681 char buf[MAX_BUF]; 627 char buf[MAX_BUF];
682 628
683 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 629 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
684 op = get_object (); 630 op = get_object ();
685 op->name = op->name_pl = buf; 631 op->name = op->name_pl = buf;
781} 727}
782 728
783/* 729/*
784 * Adds an archetype to the hashtable. 730 * Adds an archetype to the hashtable.
785 */ 731 */
786 732void
787static void 733archetype::hash_add ()
788add_arch (archetype *at)
789{ 734{
790#if USE_UNORDERED_MAP 735#if USE_UNORDERED_MAP
791 ht.insert (std::make_pair ((size_t) (const char *) at->name, at)); 736 ht.insert (std::make_pair ((size_t) (const char *) name, this));
792#endif 737#else
793 738
794 int index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 739 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
795 740
796 for (;;) 741 for (;;)
797 { 742 {
798 if (arch_table[index] == NULL) 743 if (!arch_table[index])
799 { 744 {
800 arch_table[index] = at; 745 arch_table[index] = this;
801 return; 746 break;
802 } 747 }
803 748
804 if (++index == ARCHTABLE) 749 if (++index == ARCHTABLE)
805 index = 0; 750 index = 0;
806 751
807 if (index == org_index) 752 if (index == org_index)
808 fatal (ARCHTABLE_TOO_SMALL); 753 fatal (ARCHTABLE_TOO_SMALL);
809 } 754 }
755#endif
756}
757
758void
759archetype::hash_del ()
760{
761#if USE_UNORDERED_MAP
762# error remove this from HT
763#else
764
765 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
766
767 for (;;)
768 {
769 if (arch_table[index] == this)
770 {
771 arch_table[index] = 0;
772 break;
773 }
774
775 if (++index == ARCHTABLE)
776 index = 0;
777
778 if (index == org_index)
779 break;
780 }
781#endif
810} 782}
811 783
812/* 784/*
813 * Returns the first archetype using the given type. 785 * Returns the first archetype using the given type.
814 * Used in treasure-generation. 786 * Used in treasure-generation.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines