ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
(Generate patch)

Comparing deliantra/server/common/object.C (file contents):
Revision 1.30 by root, Mon Sep 11 20:28:37 2006 UTC vs.
Revision 1.41 by root, Thu Sep 14 01:12:28 2006 UTC

29#include <stdio.h> 29#include <stdio.h>
30#include <sys/types.h> 30#include <sys/types.h>
31#include <sys/uio.h> 31#include <sys/uio.h>
32#include <object.h> 32#include <object.h>
33#include <funcpoint.h> 33#include <funcpoint.h>
34#include <skills.h>
35#include <loader.h> 34#include <loader.h>
36 35
37int nrofallocobjects = 0; 36int nrofallocobjects = 0;
37static UUID uuid;
38const uint64 UUID_SKIP = 1<<19;
38 39
39object *objects; /* Pointer to the list of used objects */ 40object *objects; /* Pointer to the list of used objects */
40object *active_objects; /* List of active objects that need to be processed */ 41object *active_objects; /* List of active objects that need to be processed */
41 42
42short freearr_x[SIZEOFFREE] = { 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1, 43short freearr_x[SIZEOFFREE] = { 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1,
50}; 51};
51int freedir[SIZEOFFREE] = { 52int freedir[SIZEOFFREE] = {
52 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8, 53 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8,
53 1, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8 54 1, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8
54}; 55};
56
57static void
58write_uuid (void)
59{
60 char filename1[MAX_BUF], filename2[MAX_BUF];
61
62 sprintf (filename1, "%s/uuid", settings.localdir);
63 sprintf (filename2, "%s/uuid~", settings.localdir);
64
65 FILE *fp;
66
67 if (!(fp = fopen (filename2, "w")))
68 {
69 LOG (llevError, "ERROR: cannot open %s for writing, unable to write UUID!\n", filename2);
70 return;
71 }
72
73 fprintf (fp, "<1,%llx>\n", (unsigned long long)uuid.seq + UUID_SKIP * 2);
74 fclose (fp);
75 rename (filename2, filename1);
76}
77
78static void
79read_uuid (void)
80{
81 char filename[MAX_BUF];
82
83 sprintf (filename, "%s/uuid", settings.localdir);
84
85 FILE *fp;
86
87 if (!(fp = fopen (filename, "r")))
88 {
89 if (errno == ENOENT)
90 {
91 LOG (llevInfo, "RESET uid to 1\n");
92 uuid.seq = 0;
93 write_uuid ();
94 return;
95 }
96
97 LOG (llevError, "FATAL: cannot open %s for reading!\n", filename);
98 _exit (1);
99 }
100
101 int version;
102 unsigned long long uid;
103 if (2 != fscanf (fp, "<%d,%llx>\n", &version, &uid) || version != 1)
104 {
105 LOG (llevError, "FATAL: error reading uid from %s!\n", filename);
106 _exit (1);
107 }
108
109 uuid.seq = uid;
110 write_uuid ();
111 LOG (llevDebug, "read UID: %lld\n", uid);
112 fclose (fp);
113}
114
115UUID
116gen_uuid ()
117{
118 UUID uid;
119
120 uid.seq = ++uuid.seq;
121
122 if (!(uuid.seq & (UUID_SKIP - 1)))
123 write_uuid ();
124
125 return uid;
126}
127
128void
129init_uuid ()
130{
131 read_uuid ();
132}
55 133
56/* Returns TRUE if every key_values in wants has a partner with the same value in has. */ 134/* Returns TRUE if every key_values in wants has a partner with the same value in has. */
57static int 135static int
58compare_ob_value_lists_one (const object *wants, const object *has) 136compare_ob_value_lists_one (const object *wants, const object *has)
59{ 137{
255 { 333 {
256 if (inv->inv) 334 if (inv->inv)
257 sum_weight (inv); 335 sum_weight (inv);
258 sum += inv->carrying + inv->weight * (inv->nrof ? inv->nrof : 1); 336 sum += inv->carrying + inv->weight * (inv->nrof ? inv->nrof : 1);
259 } 337 }
338
260 if (op->type == CONTAINER && op->stats.Str) 339 if (op->type == CONTAINER && op->stats.Str)
261 sum = (sum * (100 - op->stats.Str)) / 100; 340 sum = (sum * (100 - op->stats.Str)) / 100;
341
262 if (op->carrying != sum) 342 if (op->carrying != sum)
263 op->carrying = sum; 343 op->carrying = sum;
344
264 return sum; 345 return sum;
265} 346}
266 347
267/** 348/**
268 * Return the outermost environment object for a given object. 349 * Return the outermost environment object for a given object.
417 */ 498 */
418 499
419object * 500object *
420find_object_name (const char *str) 501find_object_name (const char *str)
421{ 502{
422 const char *name = shstr::find (str); 503 shstr_cmp str_ (str);
423 object *op; 504 object *op;
424 505
425 for (op = objects; op != NULL; op = op->next) 506 for (op = objects; op != NULL; op = op->next)
426 if (&op->name == name) 507 if (op->name == str_)
427 break; 508 break;
428 509
429 return op; 510 return op;
430} 511}
431 512
623/* 704/*
624 * Updates the speed of an object. If the speed changes from 0 to another 705 * Updates the speed of an object. If the speed changes from 0 to another
625 * value, or vice versa, then add/remove the object from the active list. 706 * value, or vice versa, then add/remove the object from the active list.
626 * This function needs to be called whenever the speed of an object changes. 707 * This function needs to be called whenever the speed of an object changes.
627 */ 708 */
628
629void 709void
630update_ob_speed (object *op) 710update_ob_speed (object *op)
631{ 711{
632 extern int arch_init; 712 extern int arch_init;
633 713
642 abort (); 722 abort ();
643#else 723#else
644 op->speed = 0; 724 op->speed = 0;
645#endif 725#endif
646 } 726 }
727
647 if (arch_init) 728 if (arch_init)
648 {
649 return; 729 return;
650 } 730
651 if (FABS (op->speed) > MIN_ACTIVE_SPEED) 731 if (FABS (op->speed) > MIN_ACTIVE_SPEED)
652 { 732 {
653 /* If already on active list, don't do anything */ 733 /* If already on active list, don't do anything */
654 if (op->active_next || op->active_prev || op == active_objects) 734 if (op->active_next || op->active_prev || op == active_objects)
655 return; 735 return;
656 736
657 /* process_events() expects us to insert the object at the beginning 737 /* process_events() expects us to insert the object at the beginning
658 * of the list. */ 738 * of the list. */
659 op->active_next = active_objects; 739 op->active_next = active_objects;
740
660 if (op->active_next != NULL) 741 if (op->active_next != NULL)
661 op->active_next->active_prev = op; 742 op->active_next->active_prev = op;
743
662 active_objects = op; 744 active_objects = op;
663 } 745 }
664 else 746 else
665 { 747 {
666 /* If not on the active list, nothing needs to be done */ 748 /* If not on the active list, nothing needs to be done */
668 return; 750 return;
669 751
670 if (op->active_prev == NULL) 752 if (op->active_prev == NULL)
671 { 753 {
672 active_objects = op->active_next; 754 active_objects = op->active_next;
755
673 if (op->active_next != NULL) 756 if (op->active_next != NULL)
674 op->active_next->active_prev = NULL; 757 op->active_next->active_prev = NULL;
675 } 758 }
676 else 759 else
677 { 760 {
678 op->active_prev->active_next = op->active_next; 761 op->active_prev->active_next = op->active_next;
762
679 if (op->active_next) 763 if (op->active_next)
680 op->active_next->active_prev = op->active_prev; 764 op->active_next->active_prev = op->active_prev;
681 } 765 }
766
682 op->active_next = NULL; 767 op->active_next = NULL;
683 op->active_prev = NULL; 768 op->active_prev = NULL;
684 } 769 }
685} 770}
686 771
833 if (op->more != NULL) 918 if (op->more != NULL)
834 update_object (op->more, action); 919 update_object (op->more, action);
835} 920}
836 921
837static unordered_vector<object *> mortals; 922static unordered_vector<object *> mortals;
838static std::vector<object *> freed; 923static std::vector<object *, slice_allocator <object *> > freed;
839 924
840void object::free_mortals () 925void object::free_mortals ()
841{ 926{
842 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();) 927 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();)
843 if ((*i)->refcnt) 928 if ((*i)->refcnt)
844 ++i; // further delay freeing 929 ++i; // further delay freeing
845 else 930 else
846 { 931 {
932 //printf ("free_mortal(%p,%ld,%ld)\n", *i, pticks, (*i)->count);//D
847 freed.push_back (*i);//D 933 //freed.push_back (*i);//D
848 //delete *i; 934 delete *i;
849 mortals.erase (i); 935 mortals.erase (i);
850 } 936 }
851 937
852 if (mortals.size())//D 938 if (mortals.size() && 0)//D
853 LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D 939 LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D
854} 940}
855 941
856object::object () 942object::object ()
857{ 943{
868} 954}
869 955
870void object::link () 956void object::link ()
871{ 957{
872 count = ++ob_count; 958 count = ++ob_count;
959 uuid = gen_uuid ();
873 960
874 prev = 0; 961 prev = 0;
875 next = objects; 962 next = objects;
876 963
877 if (objects) 964 if (objects)
880 objects = this; 967 objects = this;
881} 968}
882 969
883void object::unlink () 970void object::unlink ()
884{ 971{
885 count = 0; 972 //count = 0;//D
886 973 if (!prev && !next) return;//D
887 /* Remove this object from the list of used objects */
888 if (prev)
889 {
890 prev->next = next;
891 prev = 0;
892 }
893
894 if (next)
895 {
896 next->prev = prev;
897 next = 0;
898 }
899 974
900 if (this == objects) 975 if (this == objects)
901 objects = next; 976 objects = next;
977
978 /* Remove this object from the list of used objects */
979 if (prev) prev->next = next;
980 if (next) next->prev = prev;
981
982 prev = 0;
983 next = 0;
902} 984}
903 985
904object *object::create () 986object *object::create ()
905{ 987{
906 object * 988 object *op;
907 op;
908 989
909 if (freed.empty ()) 990 if (freed.empty ())
910 op = new object; 991 op = new object;
911 else 992 else
912 { 993 {
934void object::free (bool free_inventory) 1015void object::free (bool free_inventory)
935{ 1016{
936 if (QUERY_FLAG (this, FLAG_FREED)) 1017 if (QUERY_FLAG (this, FLAG_FREED))
937 return; 1018 return;
938 1019
1020 if (QUERY_FLAG (this, FLAG_FRIENDLY))
1021 remove_friendly_object (this);
1022
939 if (!QUERY_FLAG (this, FLAG_REMOVED)) 1023 if (!QUERY_FLAG (this, FLAG_REMOVED))
940 remove_ob (this); 1024 remove_ob (this);
941 1025
942 if (QUERY_FLAG (this, FLAG_FRIENDLY))
943 remove_friendly_object (this);
944
945 SET_FLAG (this, FLAG_FREED); 1026 SET_FLAG (this, FLAG_FREED);
1027
1028 //printf ("free(%p,%ld,%ld)\n", this, pticks, count);//D
946 1029
947 if (more) 1030 if (more)
948 { 1031 {
949 more->free (free_inventory); 1032 more->free (free_inventory);
950 more = 0; 1033 more = 0;
954 { 1037 {
955 /* Only if the space blocks everything do we not process - 1038 /* Only if the space blocks everything do we not process -
956 * if some form of movement is allowed, let objects 1039 * if some form of movement is allowed, let objects
957 * drop on that space. 1040 * drop on that space.
958 */ 1041 */
959 if (free_inventory || !map || map->in_memory != MAP_IN_MEMORY || (GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL)) 1042 if (free_inventory || !map || map->in_memory != MAP_IN_MEMORY || GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL)
960 { 1043 {
961 object *op = inv; 1044 object *op = inv;
962 1045
963 while (op) 1046 while (op)
964 { 1047 {
1220 * This function goes through all objects below and including top, and 1303 * This function goes through all objects below and including top, and
1221 * merges op to the first matching object. 1304 * merges op to the first matching object.
1222 * If top is NULL, it is calculated. 1305 * If top is NULL, it is calculated.
1223 * Returns pointer to object if it succeded in the merge, otherwise NULL 1306 * Returns pointer to object if it succeded in the merge, otherwise NULL
1224 */ 1307 */
1225
1226object * 1308object *
1227merge_ob (object *op, object *top) 1309merge_ob (object *op, object *top)
1228{ 1310{
1229 if (!op->nrof) 1311 if (!op->nrof)
1230 return 0; 1312 return 0;
2651 2733
2652 if (tempfile == NULL) 2734 if (tempfile == NULL)
2653 { 2735 {
2654 LOG (llevError, "Error - Unable to access load object temp file\n"); 2736 LOG (llevError, "Error - Unable to access load object temp file\n");
2655 return NULL; 2737 return NULL;
2656 }; 2738 }
2739
2657 fprintf (tempfile, obstr); 2740 fprintf (tempfile, obstr);
2658 fclose (tempfile); 2741 fclose (tempfile);
2659 2742
2660 op = get_object (); 2743 op = get_object ();
2661 2744
2718 * The returned string is shared. 2801 * The returned string is shared.
2719 */ 2802 */
2720const char * 2803const char *
2721get_ob_key_value (const object *op, const char *const key) 2804get_ob_key_value (const object *op, const char *const key)
2722{ 2805{
2723 key_value * 2806 key_value *link;
2724 link; 2807 shstr_cmp canonical_key (key);
2725 const char *
2726 canonical_key;
2727 2808
2728 canonical_key = shstr::find (key);
2729
2730 if (canonical_key == NULL) 2809 if (!canonical_key)
2731 { 2810 {
2732 /* 1. There being a field named key on any object 2811 /* 1. There being a field named key on any object
2733 * implies there'd be a shared string to find. 2812 * implies there'd be a shared string to find.
2734 * 2. Since there isn't, no object has this field. 2813 * 2. Since there isn't, no object has this field.
2735 * 3. Therefore, *this* object doesn't have this field. 2814 * 3. Therefore, *this* object doesn't have this field.
2736 */ 2815 */
2737 return NULL; 2816 return 0;
2738 } 2817 }
2739 2818
2740 /* This is copied from get_ob_key_link() above - 2819 /* This is copied from get_ob_key_link() above -
2741 * only 4 lines, and saves the function call overhead. 2820 * only 4 lines, and saves the function call overhead.
2742 */ 2821 */
2743 for (link = op->key_values; link != NULL; link = link->next) 2822 for (link = op->key_values; link; link = link->next)
2744 {
2745 if (link->key == canonical_key) 2823 if (link->key == canonical_key)
2746 {
2747 return link->value; 2824 return link->value;
2748 } 2825
2749 }
2750 return NULL; 2826 return 0;
2751} 2827}
2752 2828
2753 2829
2754/* 2830/*
2755 * Updates the canonical_key in op to value. 2831 * Updates the canonical_key in op to value.
2840{ 2916{
2841 shstr key_ (key); 2917 shstr key_ (key);
2842 2918
2843 return set_ob_key_value_s (op, key_, value, add_key); 2919 return set_ob_key_value_s (op, key_, value, add_key);
2844} 2920}
2921
2922object::depth_iterator::depth_iterator (object *container)
2923: iterator_base (container)
2924{
2925 while (item->inv)
2926 item = item->inv;
2927}
2928
2929void
2930object::depth_iterator::next ()
2931{
2932 if (item->below)
2933 {
2934 item = item->below;
2935
2936 while (item->inv)
2937 item = item->inv;
2938 }
2939 else
2940 item = item->env;
2941}
2942
2943// return a suitable string describing an objetc in enough detail to find it
2944const char *
2945object::debug_desc (char *info) const
2946{
2947 char info2[256 * 3];
2948 char *p = info;
2949
2950 p += snprintf (p, 256, "%d=\"%s%s%s\"",
2951 count,
2952 &name,
2953 title ? " " : "",
2954 title ? (const char *)title : "");
2955
2956 if (env)
2957 p += snprintf (p, 256, "(in %s)", env->debug_desc (info2));
2958
2959 if (map)
2960 p += snprintf (p, 256, "(on %s@%d+%d)", map->path, x, y);
2961
2962 return info;
2963}
2964
2965const char *
2966object::debug_desc () const
2967{
2968 static char info[256 * 3];
2969 return debug_desc (info);
2970}
2971

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines