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.18 by root, Tue Sep 12 20:55:40 2006 UTC vs.
Revision 1.30 by root, Wed Dec 13 00:42:03 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").
75 * - the archetype found or null if nothing was found. 75 * - the archetype found or null if nothing was found.
76 */ 76 */
77archetype * 77archetype *
78find_archetype_by_object_name (const char *name) 78find_archetype_by_object_name (const char *name)
79{ 79{
80 archetype * 80 archetype *at;
81 at;
82 81
83 if (name == NULL) 82 if (name == NULL)
84 return (archetype *) NULL; 83 return (archetype *) NULL;
85 84
86 for (at = first_archetype; at != NULL; at = at->next) 85 for (at = first_archetype; at != NULL; at = at->next)
97 * except that it considers only items of the given type. 96 * except that it considers only items of the given type.
98 */ 97 */
99archetype * 98archetype *
100find_archetype_by_object_type_name (int type, const char *name) 99find_archetype_by_object_type_name (int type, const char *name)
101{ 100{
102 archetype * 101 archetype *at;
103 at;
104 102
105 if (name == NULL) 103 if (name == NULL)
106 return NULL; 104 return NULL;
107 105
108 for (at = first_archetype; at != NULL; at = at->next) 106 for (at = first_archetype; at != NULL; at = at->next)
182 { 180 {
183 tmpname[i] = 0; 181 tmpname[i] = 0;
184 at = find_archetype_by_object_name (tmpname); 182 at = find_archetype_by_object_name (tmpname);
185 183
186 if (at != NULL) 184 if (at != NULL)
187 {
188 return arch_to_object (at); 185 return arch_to_object (at);
189 }
190 } 186 }
191 187
192 return create_singularity (name); 188 return create_singularity (name);
193} 189}
194 190
210 * Last, make a check on the full name. 206 * Last, make a check on the full name.
211 */ 207 */
212int 208int
213item_matched_string (object *pl, object *op, const char *name) 209item_matched_string (object *pl, object *op, const char *name)
214{ 210{
215 char *
216 cp,
217 local_name[MAX_BUF]; 211 char *cp, local_name[MAX_BUF];
218 int 212 int count, retval = 0;
219 count,
220 retval = 0;
221 213
222 strcpy (local_name, name); /* strtok is destructive to name */ 214 strcpy (local_name, name); /* strtok is destructive to name */
223 215
224 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ",")) 216 for (cp = strtok (local_name, ","); cp; cp = strtok (NULL, ","))
225 { 217 {
277 retval = 15; 269 retval = 15;
278 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp))) 270 else if (!strncasecmp (cp, query_base_name (op, 0), strlen (cp)))
279 retval = 14; 271 retval = 14;
280 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp))) 272 else if (!strncasecmp (cp, query_base_name (op, 1), strlen (cp)))
281 retval = 14; 273 retval = 14;
282
283 /* Do substring checks, so things like 'Str+1' will match. 274 /* Do substring checks, so things like 'Str+1' will match.
284 * retval of these should perhaps be lower - they are lower 275 * retval of these should perhaps be lower - they are lower
285 * then the specific strcasecmp aboves, but still higher than 276 * then the specific strcasecmp aboves, but still higher than
286 * some other match criteria. 277 * some other match criteria.
287 */ 278 */
289 retval = 12; 280 retval = 12;
290 else if (strstr (query_base_name (op, 0), cp)) 281 else if (strstr (query_base_name (op, 0), cp))
291 retval = 12; 282 retval = 12;
292 else if (strstr (query_short_name (op), cp)) 283 else if (strstr (query_short_name (op), cp))
293 retval = 12; 284 retval = 12;
294
295 /* Check against plural/non plural based on count. */ 285 /* Check against plural/non plural based on count. */
296 else if (count > 1 && !strcasecmp (cp, op->name_pl)) 286 else if (count > 1 && !strcasecmp (cp, op->name_pl))
297 {
298 retval = 6; 287 retval = 6;
299 }
300 else if (count == 1 && !strcasecmp (op->name, cp)) 288 else if (count == 1 && !strcasecmp (op->name, cp))
301 {
302 retval = 6; 289 retval = 6;
303 }
304 /* base name matched - not bad */ 290 /* base name matched - not bad */
305 else if (strcasecmp (cp, op->name) == 0 && !count) 291 else if (strcasecmp (cp, op->name) == 0 && !count)
306 retval = 4; 292 retval = 4;
307 /* Check for partial custom name, but give a real low priority */ 293 /* Check for partial custom name, but give a real low priority */
308 else if (op->custom_name && strstr (op->custom_name, cp)) 294 else if (op->custom_name && strstr (op->custom_name, cp))
310 296
311 if (retval) 297 if (retval)
312 { 298 {
313 if (pl->type == PLAYER) 299 if (pl->type == PLAYER)
314 pl->contr->count = count; 300 pl->contr->count = count;
301
315 return retval; 302 return retval;
316 } 303 }
317 } 304 }
305
318 return 0; 306 return 0;
319} 307}
320 308
321/* 309/*
322 * Initialises the internal linked list of archetypes (read from file). 310 * Initialises the internal linked list of archetypes (read from file).
327void 315void
328init_archetypes (void) 316init_archetypes (void)
329{ /* called from add_player() and edit() */ 317{ /* called from add_player() and edit() */
330 if (first_archetype != NULL) /* Only do this once */ 318 if (first_archetype != NULL) /* Only do this once */
331 return; 319 return;
320
332 arch_init = 1; 321 arch_init = 1;
333 load_archetypes (); 322 load_archetypes ();
334 arch_init = 0; 323 arch_init = 0;
335 empty_archetype = find_archetype ("empty_archetype"); 324 empty_archetype = archetype::find ("empty_archetype");
336 325
337/* init_blocksview();*/ 326/* init_blocksview();*/
338} 327}
339 328
340/* 329/*
364 */ 353 */
365 354
366void 355void
367init_archetable (void) 356init_archetable (void)
368{ 357{
369 archetype * 358 archetype *at;
370 at;
371 359
372 LOG (llevDebug, " Setting up archetable...\n"); 360 LOG (llevDebug, " Setting up archetable...\n");
373 361
374 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)
375 add_arch (at); 363 at->hash_add ();
376 364
377 LOG (llevDebug, "done\n"); 365 LOG (llevDebug, "done\n");
378} 366}
379 367
380/*
381 * Dumps an archetype to debug-level output.
382 */
383
384void
385dump_arch (archetype *at)
386{
387 dump_object (&at->clone);
388}
389
390/*
391 * Dumps _all_ archetypes to debug-level output.
392 * If you run crossfire with debug, and enter DM-mode, you can trigger
393 * this with the O key.
394 */
395
396void
397dump_all_archetypes (void)
398{
399 archetype *
400 at;
401
402 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more)
403 {
404 dump_arch (at);
405 fprintf (logfile, "%s\n", errmsg);
406 }
407}
408
409void 368void
410free_all_archs (void) 369free_all_archs (void)
411{ 370{
412 archetype * 371 archetype *at, *next;
413 at, *
414 next;
415 int
416 i = 0, f = 0; 372 int i = 0, f = 0;
417 373
418 for (at = first_archetype; at != NULL; at = next) 374 for (at = first_archetype; at != NULL; at = next)
419 { 375 {
420 if (at->more) 376 if (at->more)
421 next = at->more; 377 next = at->more;
425 delete 381 delete
426 at; 382 at;
427 383
428 i++; 384 i++;
429 } 385 }
386
430 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f); 387 LOG (llevDebug, "Freed %d archetypes, %d faces\n", i, f);
431} 388}
432 389
433archetype::archetype () 390archetype::archetype ()
434{ 391{
435 clear_object (&clone); /* to initial state other also */ 392 clear_object (&clone); /* to initial state other also */
436 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_object() */ 393 CLEAR_FLAG (&clone, FLAG_FREED); /* This shouldn't matter, since copy_to */
437 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */ 394 SET_FLAG (&clone, FLAG_REMOVED); /* doesn't copy these flags... */
438} 395}
439 396
440archetype::~archetype () 397archetype::~archetype ()
441{ 398{
446 * of archetype-structures. 403 * of archetype-structures.
447 */ 404 */
448void 405void
449first_arch_pass (object_thawer & fp) 406first_arch_pass (object_thawer & fp)
450{ 407{
451 archetype * 408 archetype *head = 0, *last_more = 0;
452 at, *
453 head = NULL, *last_more = NULL;
454 409
410 archetype *at = new archetype;
455 at->clone.arch = first_archetype = at = new archetype; 411 at->clone.arch = first_archetype = at;
456 412
457 while (int i = load_object (fp, &at->clone, 0)) 413 while (int i = load_object (fp, &at->clone, 0))
458 { 414 {
459 at->clone.speed_left = (float) (-0.1); 415 at->clone.speed_left = (float) (-0.1);
460 /* 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
527 */ 483 */
528 484
529void 485void
530second_arch_pass (object_thawer & thawer) 486second_arch_pass (object_thawer & thawer)
531{ 487{
532 char
533 buf[MAX_BUF], *
534 variable = buf, *argument, *cp; 488 char buf[MAX_BUF], *variable = buf, *argument, *cp;
535 archetype *
536 at = NULL, *other; 489 archetype *at = NULL, *other;
537 490
538 while (fgets (buf, MAX_BUF, thawer) != NULL) 491 while (fgets (buf, MAX_BUF, thawer) != NULL)
539 { 492 {
540 if (*buf == '#') 493 if (*buf == '#')
541 continue; 494 continue;
549 cp--; 502 cp--;
550 } 503 }
551 } 504 }
552 if (!strcmp ("Object", variable)) 505 if (!strcmp ("Object", variable))
553 { 506 {
554 if ((at = find_archetype (argument)) == NULL) 507 if ((at = archetype::find (argument)) == NULL)
555 LOG (llevError, "Warning: failed to find arch %s\n", argument); 508 LOG (llevError, "Warning: failed to find arch %s\n", argument);
556 } 509 }
557 else if (!strcmp ("other_arch", variable)) 510 else if (!strcmp ("other_arch", variable))
558 { 511 {
559 if (at != NULL && at->clone.other_arch == NULL) 512 if (at != NULL && at->clone.other_arch == NULL)
560 { 513 {
561 if ((other = find_archetype (argument)) == NULL) 514 if ((other = archetype::find (argument)) == NULL)
562 LOG (llevError, "Warning: failed to find other_arch %s\n", argument); 515 LOG (llevError, "Warning: failed to find other_arch %s\n", argument);
563 else if (at != NULL) 516 else if (at != NULL)
564 at->clone.other_arch = other; 517 at->clone.other_arch = other;
565 } 518 }
566 } 519 }
567 else if (!strcmp ("randomitems", variable)) 520 else if (!strcmp ("randomitems", variable))
568 { 521 {
569 if (at != NULL) 522 if (at != NULL)
570 { 523 {
571 treasurelist *
572 tl = find_treasurelist (argument); 524 treasurelist *tl = find_treasurelist (argument);
573 525
574 if (tl == NULL) 526 if (tl == NULL)
575 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);
576 else 528 else
577 at->clone.randomitems = tl; 529 at->clone.randomitems = tl;
582 534
583#ifdef DEBUG 535#ifdef DEBUG
584void 536void
585check_generators (void) 537check_generators (void)
586{ 538{
587 archetype * 539 archetype *at;
588 at;
589 540
590 for (at = first_archetype; at != NULL; at = at->next) 541 for (at = first_archetype; at != NULL; at = at->next)
591 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)
592 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);
593} 544}
601 */ 552 */
602 553
603void 554void
604load_archetypes (void) 555load_archetypes (void)
605{ 556{
606 char
607 filename[MAX_BUF]; 557 char filename[MAX_BUF];
608
609#if TIME_ARCH_LOAD
610 struct timeval
611 tv1,
612 tv2;
613#endif
614 558
615 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes); 559 sprintf (filename, "%s/%s", settings.datadir, settings.archetypes);
616 LOG (llevDebug, "Reading archetypes from %s:\n", filename); 560 LOG (llevDebug, "Reading archetypes from %s:\n", filename);
617 561
618 { 562 {
650 */ 594 */
651 595
652object * 596object *
653arch_to_object (archetype *at) 597arch_to_object (archetype *at)
654{ 598{
655 object * 599 object *op;
656 op;
657 600
658 if (at == NULL) 601 if (at == NULL)
659 { 602 {
660 if (warn_archetypes) 603 if (warn_archetypes)
661 LOG (llevError, "Couldn't find archetype.\n"); 604 LOG (llevError, "Couldn't find archetype.\n");
662 605
663 return NULL; 606 return NULL;
664 } 607 }
665 608
666 op = get_object (); 609 op = at->clone.clone ();
667 copy_object (&at->clone, op);
668 op->arch = at; 610 op->arch = at;
669 op->instantiate (); 611 op->instantiate ();
670 return op; 612 return op;
671} 613}
672 614
678 */ 620 */
679 621
680object * 622object *
681create_singularity (const char *name) 623create_singularity (const char *name)
682{ 624{
683 object * 625 object *op;
684 op;
685 char
686 buf[MAX_BUF]; 626 char buf[MAX_BUF];
687 627
688 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name); 628 sprintf (buf, "%s (%s)", ARCH_SINGULARITY, name);
689 op = get_object (); 629 op = object::create ();
690 op->name = op->name_pl = buf; 630 op->name = op->name_pl = buf;
691 SET_FLAG (op, FLAG_NO_PICK); 631 SET_FLAG (op, FLAG_NO_PICK);
692 return op; 632 return op;
693} 633}
694 634
698 */ 638 */
699 639
700object * 640object *
701get_archetype (const char *name) 641get_archetype (const char *name)
702{ 642{
703 archetype * 643 archetype *at = archetype::find (name);
704 at;
705 644
706 at = find_archetype (name); 645 if (!at)
707 if (at == NULL)
708 return create_singularity (name); 646 return create_singularity (name);
709 647
710 return arch_to_object (at); 648 return arch_to_object (at);
711} 649}
712 650
715 */ 653 */
716 654
717unsigned long 655unsigned long
718hasharch (const char *str, int tablesize) 656hasharch (const char *str, int tablesize)
719{ 657{
720 unsigned long 658 unsigned long hash = 0;
721 hash = 0;
722 unsigned int 659 unsigned int i = 0;
723 i = 0;
724 const char * 660 const char *p;
725 p;
726 661
727 /* use the one-at-a-time hash function, which supposedly is 662 /* use the one-at-a-time hash function, which supposedly is
728 * better than the djb2-like one used by perl5.005, but 663 * better than the djb2-like one used by perl5.005, but
729 * certainly is better then the bug used here before. 664 * certainly is better then the bug used here before.
730 * see http://burtleburtle.net/bob/hash/doobs.html 665 * see http://burtleburtle.net/bob/hash/doobs.html
747 * Finds, using the hashtable, which archetype matches the given name. 682 * Finds, using the hashtable, which archetype matches the given name.
748 * returns a pointer to the found archetype, otherwise NULL. 683 * returns a pointer to the found archetype, otherwise NULL.
749 */ 684 */
750 685
751archetype * 686archetype *
752find_archetype (const char *name) 687archetype::find (const char *name)
753{ 688{
754#if USE_UNORDERED_MAP
755 name = shstr::find (name);
756
757 if (!name) 689 if (!name)
758 return 0; 690 return 0;
759 691
760 HT::const_iterator i = ht.find ((size_t) name); 692#if USE_UNORDERED_MAP
693 AUTODECL (i, ht.find ((size_t) name));
761 694
762 if (i == ht.end ()) 695 if (i == ht.end ())
763 return 0; 696 return 0;
764 else 697 else
765 return i->second; 698 return i->second;
766#endif 699#endif
767 700
768 archetype * 701 archetype *at;
769 at;
770 unsigned long 702 unsigned long index;
771 index;
772
773 if (name == NULL)
774 return (archetype *) NULL;
775 703
776 index = hasharch (name, ARCHTABLE); 704 index = hasharch (name, ARCHTABLE);
777 arch_search++; 705 arch_search++;
778 for (;;) 706 for (;;)
779 { 707 {
780 at = arch_table[index]; 708 at = arch_table[index];
709
781 if (at == NULL) 710 if (at == NULL)
782 { 711 {
783 if (warn_archetypes) 712 if (warn_archetypes)
784 LOG (llevError, "Couldn't find archetype %s\n", name); 713 LOG (llevError, "Couldn't find archetype %s\n", name);
714
785 return NULL; 715 return NULL;
786 } 716 }
717
787 arch_cmp++; 718 arch_cmp++;
719
788 if (!strcmp ((const char *) at->name, name)) 720 if (!strcmp ((const char *) at->name, name))
789 return at; 721 return at;
722
790 if (++index >= ARCHTABLE) 723 if (++index >= ARCHTABLE)
791 index = 0; 724 index = 0;
792 } 725 }
793} 726}
794 727
795/* 728/*
796 * Adds an archetype to the hashtable. 729 * Adds an archetype to the hashtable.
797 */ 730 */
798 731void
799static void 732archetype::hash_add ()
800add_arch (archetype *at)
801{ 733{
802#if USE_UNORDERED_MAP 734#if USE_UNORDERED_MAP
803 ht.insert (std::make_pair ((size_t) (const char *) at->name, at)); 735 ht.insert (std::make_pair ((size_t) (const char *) name, this));
804#endif 736#else
805 737
806 int
807 index = hasharch ((const char *) at->name, ARCHTABLE), org_index = index; 738 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
808 739
809 for (;;) 740 for (;;)
810 { 741 {
811 if (arch_table[index] == NULL) 742 if (!arch_table[index])
812 { 743 {
813 arch_table[index] = at; 744 arch_table[index] = this;
814 return; 745 break;
815 } 746 }
816 747
817 if (++index == ARCHTABLE) 748 if (++index == ARCHTABLE)
818 index = 0; 749 index = 0;
819 750
820 if (index == org_index) 751 if (index == org_index)
821 fatal (ARCHTABLE_TOO_SMALL); 752 fatal (ARCHTABLE_TOO_SMALL);
822 } 753 }
754#endif
755}
756
757void
758archetype::hash_del ()
759{
760#if USE_UNORDERED_MAP
761# error remove this from HT
762#else
763
764 int index = hasharch ((const char *) name, ARCHTABLE), org_index = index;
765
766 for (;;)
767 {
768 if (arch_table[index] == this)
769 {
770 arch_table[index] = 0;
771 break;
772 }
773
774 if (++index == ARCHTABLE)
775 index = 0;
776
777 if (index == org_index)
778 break;
779 }
780#endif
823} 781}
824 782
825/* 783/*
826 * Returns the first archetype using the given type. 784 * Returns the first archetype using the given type.
827 * Used in treasure-generation. 785 * Used in treasure-generation.
828 */ 786 */
829 787
830archetype * 788archetype *
831type_to_archetype (int type) 789type_to_archetype (int type)
832{ 790{
833 archetype * 791 archetype *at;
834 at;
835 792
836 for (at = first_archetype; at != NULL; at = (at->more == NULL) ? at->next : at->more) 793 for (at = first_archetype; at; at = at->more == 0 ? at->next : at->more)
837 if (at->clone.type == type) 794 if (at->clone.type == type)
838 return at; 795 return at;
796
839 return NULL; 797 return 0;
840} 798}
841 799
842/* 800/*
843 * Returns a new object copied from the first archetype matching 801 * Returns a new object copied from the first archetype matching
844 * the given type. 802 * the given type.
846 */ 804 */
847 805
848object * 806object *
849clone_arch (int type) 807clone_arch (int type)
850{ 808{
851 archetype * 809 archetype *at;
852 at;
853 object *
854 op = get_object ();
855 810
856 if ((at = type_to_archetype (type)) == NULL) 811 if ((at = type_to_archetype (type)) == NULL)
857 { 812 {
858 LOG (llevError, "Can't clone archetype %d\n", type); 813 LOG (llevError, "Can't clone archetype %d\n", type);
859 free_object (op);
860 return NULL; 814 return 0;
861 } 815 }
862 copy_object (&at->clone, op); 816
817 object *op = at->clone.clone ();
863 op->instantiate (); 818 op->instantiate ();
864 return op; 819 return op;
865} 820}
866 821
867/* 822/*
869 */ 824 */
870 825
871object * 826object *
872object_create_arch (archetype *at) 827object_create_arch (archetype *at)
873{ 828{
874 object * 829 object *op, *prev = 0, *head = 0;
875 op, *
876 prev = NULL, *head = NULL;
877 830
878 while (at) 831 while (at)
879 { 832 {
880 op = arch_to_object (at); 833 op = arch_to_object (at);
881 op->x = at->clone.x; 834 op->x = at->clone.x;
882 op->y = at->clone.y; 835 op->y = at->clone.y;
836
883 if (head) 837 if (head)
884 op->head = head, prev->more = op; 838 op->head = head, prev->more = op;
839
885 if (!head) 840 if (!head)
886 head = op; 841 head = op;
842
887 prev = op; 843 prev = op;
888 at = at->more; 844 at = at->more;
889 } 845 }
846
890 return (head); 847 return (head);
891} 848}
892 849
893/*** end of arch.c ***/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines