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.39 by root, Wed Sep 13 02:05:19 2006 UTC vs.
Revision 1.47 by root, Thu Sep 14 22:33:59 2006 UTC

1
2/* 1/*
3 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
4 3
5 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
6 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
17 16
18 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
19 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 20
22 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>
23*/ 22*/
24 23
25/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects. 24/* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects.
26 sub/add_weight will transcend the environment updating the carrying 25 sub/add_weight will transcend the environment updating the carrying
27 variable. */ 26 variable. */
35 34
36int nrofallocobjects = 0; 35int nrofallocobjects = 0;
37static UUID uuid; 36static UUID uuid;
38const uint64 UUID_SKIP = 1<<19; 37const uint64 UUID_SKIP = 1<<19;
39 38
40object *objects; /* Pointer to the list of used objects */
41object *active_objects; /* List of active objects that need to be processed */ 39object *active_objects; /* List of active objects that need to be processed */
42 40
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, 41short 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,
44 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1 42 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1
45}; 43};
447void 445void
448dump_all_objects (void) 446dump_all_objects (void)
449{ 447{
450 object *op; 448 object *op;
451 449
452 for (op = objects; op != NULL; op = op->next) 450 for (op = object::first; op != NULL; op = op->next)
453 { 451 {
454 dump_object (op); 452 dump_object (op);
455 fprintf (logfile, "Object %d\n:%s\n", op->count, errmsg); 453 fprintf (logfile, "Object %d\n:%s\n", op->count, errmsg);
456 } 454 }
457} 455}
483object * 481object *
484find_object (tag_t i) 482find_object (tag_t i)
485{ 483{
486 object *op; 484 object *op;
487 485
488 for (op = objects; op != NULL; op = op->next) 486 for (op = object::first; op != NULL; op = op->next)
489 if (op->count == i) 487 if (op->count == i)
490 break; 488 break;
491 return op; 489 return op;
492} 490}
493 491
501find_object_name (const char *str) 499find_object_name (const char *str)
502{ 500{
503 shstr_cmp str_ (str); 501 shstr_cmp str_ (str);
504 object *op; 502 object *op;
505 503
506 for (op = objects; op != NULL; op = op->next) 504 for (op = object::first; op != NULL; op = op->next)
507 if (op->name == str_) 505 if (op->name == str_)
508 break; 506 break;
509 507
510 return op; 508 return op;
511} 509}
512 510
513void 511void
514free_all_object_data () 512free_all_object_data ()
515{ 513{
516 LOG (llevDebug, "%d allocated objects\n", nrofallocobjects); 514 LOG (llevDebug, "%d allocated objects\n", nrofallocobjects);
517}
518
519/*
520 * Returns the object which this object marks as being the owner.
521 * A id-scheme is used to avoid pointing to objects which have been
522 * freed and are now reused. If this is detected, the owner is
523 * set to NULL, and NULL is returned.
524 * Changed 2004-02-12 - if the player is setting at the play again
525 * prompt, he is removed, and we don't want to treat him as an owner of
526 * anything, so check removed flag. I don't expect that this should break
527 * anything - once an object is removed, it is basically dead anyways.
528 */
529object *
530object::get_owner ()
531{
532 if (!owner
533 || QUERY_FLAG (owner, FLAG_FREED)
534 || QUERY_FLAG (owner, FLAG_REMOVED))
535 owner = 0;
536
537 return owner;
538} 515}
539 516
540/* 517/*
541 * Sets the owner and sets the skill and exp pointers to owner's current 518 * Sets the owner and sets the skill and exp pointers to owner's current
542 * skill and experience objects. 519 * skill and experience objects.
612 589
613 /* What is not cleared is next, prev, and count */ 590 /* What is not cleared is next, prev, and count */
614 591
615 expmul = 1.0; 592 expmul = 1.0;
616 face = blank_face; 593 face = blank_face;
617 attacked_by_count = -1;
618 594
619 if (settings.casting_time) 595 if (settings.casting_time)
620 casting_time = -1; 596 casting_time = -1;
621} 597}
622 598
917 893
918 if (op->more != NULL) 894 if (op->more != NULL)
919 update_object (op->more, action); 895 update_object (op->more, action);
920} 896}
921 897
922static unordered_vector<object *> mortals; 898object::vector object::mortals;
923static std::vector<object *, slice_allocator <object *> > freed; 899object::vector object::objects; // not yet used
900object *object::first;
924 901
925void object::free_mortals () 902void object::free_mortals ()
926{ 903{
927 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();) 904 for (AUTODECL (i, mortals.begin ()); i != mortals.end ();)
928 if ((*i)->refcnt) 905 if ((*i)->refcnt)
929 ++i; // further delay freeing 906 ++i; // further delay freeing
930 else 907 else
931 { 908 {
932 freed.push_back (*i);//D
933 //delete *i; 909 delete *i;
934 mortals.erase (i); 910 mortals.erase (i);
935 } 911 }
936 912
937 if (mortals.size() && 0)//D 913 static int lastmortals = 0;//D
914
915 if (mortals.size() != lastmortals)//D
916 {
917 lastmortals = mortals.size ();//D
938 LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D 918 LOG (llevDebug, "%d objects in mortal queue\n", lastmortals);//D
919 }
939} 920}
940 921
941object::object () 922object::object ()
942{ 923{
943 SET_FLAG (this, FLAG_REMOVED); 924 SET_FLAG (this, FLAG_REMOVED);
944 925
945 expmul = 1.0; 926 expmul = 1.0;
946 face = blank_face; 927 face = blank_face;
947 attacked_by_count = -1;
948} 928}
949 929
950object::~object () 930object::~object ()
951{ 931{
952 free_key_values (this); 932 free_key_values (this);
953} 933}
954 934
955void object::link () 935void object::link ()
956{ 936{
957 count = ++ob_count; 937 count = ++ob_count;
938 uuid = gen_uuid ();
958 939
959 prev = 0; 940 prev = 0;
960 next = objects; 941 next = object::first;
961 942
962 if (objects) 943 if (object::first)
963 objects->prev = this; 944 object::first->prev = this;
964 945
965 objects = this; 946 object::first = this;
966} 947}
967 948
968void object::unlink () 949void object::unlink ()
969{ 950{
970 count = 0; 951 //count = 0;//D
971 uuid = gen_uuid (); 952 if (!prev && !next) return;//D
972 953
973 if (this == objects) 954 if (this == object::first)
974 objects = next; 955 object::first = next;
975 956
976 /* Remove this object from the list of used objects */ 957 /* Remove this object from the list of used objects */
977 if (prev)
978 {
979 prev->next = next; 958 if (prev) prev->next = next;
959 if (next) next->prev = prev;
960
980 prev = 0; 961 prev = 0;
981 }
982
983 if (next)
984 {
985 next->prev = prev;
986 next = 0; 962 next = 0;
987 }
988} 963}
989 964
990object *object::create () 965object *object::create ()
991{ 966{
992 object *op;
993
994 if (freed.empty ())
995 op = new object; 967 object *op = new object;
996 else
997 {
998 // highly annoying, but the only way to get it stable right now
999 op = freed.back ();
1000 freed.pop_back ();
1001 op->~object ();
1002 new ((void *) op) object;
1003 }
1004
1005 op->link (); 968 op->link ();
1006 return op; 969 return op;
1007} 970}
1008 971
1009/* 972/*
1075 op = tmp; 1038 op = tmp;
1076 } 1039 }
1077 } 1040 }
1078 } 1041 }
1079 1042
1043 // clear those pointers that likely might have circular references to us
1080 owner = 0; 1044 owner = 0;
1045 enemy = 0;
1046 attacked_by = 0;
1081 1047
1082 /* Remove object from the active list */ 1048 /* Remove object from the active list */
1083 speed = 0; 1049 speed = 0;
1084 update_ob_speed (this); 1050 update_ob_speed (this);
1085 1051
1097sub_weight (object *op, signed long weight) 1063sub_weight (object *op, signed long weight)
1098{ 1064{
1099 while (op != NULL) 1065 while (op != NULL)
1100 { 1066 {
1101 if (op->type == CONTAINER) 1067 if (op->type == CONTAINER)
1102 {
1103 weight = (signed long) (weight * (100 - op->stats.Str) / 100); 1068 weight = (signed long) (weight * (100 - op->stats.Str) / 100);
1104 } 1069
1105 op->carrying -= weight; 1070 op->carrying -= weight;
1106 op = op->env; 1071 op = op->env;
1107 } 1072 }
1108} 1073}
1109 1074
1117 */ 1082 */
1118 1083
1119void 1084void
1120remove_ob (object *op) 1085remove_ob (object *op)
1121{ 1086{
1087 object *tmp, *last = 0;
1122 object * 1088 object *otmp;
1123 tmp, *
1124 last = NULL;
1125 object *
1126 otmp;
1127 1089
1128 tag_t 1090 tag_t tag;
1129 tag;
1130 int
1131 check_walk_off; 1091 int check_walk_off;
1132 mapstruct * 1092 mapstruct *m;
1133 m;
1134 1093
1135 sint16 1094 sint16 x, y;
1136 x,
1137 y;
1138 1095
1139 if (QUERY_FLAG (op, FLAG_REMOVED)) 1096 if (QUERY_FLAG (op, FLAG_REMOVED))
1140 return; 1097 return;
1141 1098
1142 SET_FLAG (op, FLAG_REMOVED); 1099 SET_FLAG (op, FLAG_REMOVED);
1330 free_object (op); 1287 free_object (op);
1331 return top; 1288 return top;
1332 } 1289 }
1333 } 1290 }
1334 1291
1335 return NULL; 1292 return 0;
1336} 1293}
1337 1294
1338/* 1295/*
1339 * same as insert_ob_in_map except it handle separate coordinates and do a clean 1296 * same as insert_ob_in_map except it handle separate coordinates and do a clean
1340 * job preparing multi-part monsters 1297 * job preparing multi-part monsters
1667 remove_ob (tmp); 1624 remove_ob (tmp);
1668 free_object (tmp); 1625 free_object (tmp);
1669 } 1626 }
1670 } 1627 }
1671 1628
1672 tmp1 = arch_to_object (find_archetype (arch_string)); 1629 tmp1 = arch_to_object (archetype::find (arch_string));
1673 1630
1674 tmp1->x = op->x; 1631 tmp1->x = op->x;
1675 tmp1->y = op->y; 1632 tmp1->y = op->y;
1676 insert_ob_in_map (tmp1, op->map, op, 0); 1633 insert_ob_in_map (tmp1, op->map, op, 0);
1677} 1634}
2735 2692
2736 if (tempfile == NULL) 2693 if (tempfile == NULL)
2737 { 2694 {
2738 LOG (llevError, "Error - Unable to access load object temp file\n"); 2695 LOG (llevError, "Error - Unable to access load object temp file\n");
2739 return NULL; 2696 return NULL;
2740 }; 2697 }
2698
2741 fprintf (tempfile, obstr); 2699 fprintf (tempfile, obstr);
2742 fclose (tempfile); 2700 fclose (tempfile);
2743 2701
2744 op = get_object (); 2702 op = get_object ();
2745 2703

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines