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.41 by root, Thu Sep 14 01:12:28 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 //printf ("free_mortal(%p,%ld,%ld)\n", *i, pticks, (*i)->count);//D
933 //freed.push_back (*i);//D
934 delete *i; 909 delete *i;
935 mortals.erase (i); 910 mortals.erase (i);
936 } 911 }
937 912
938 if (mortals.size() && 0)//D 913 static int lastmortals = 0;//D
914
915 if (mortals.size() != lastmortals)//D
916 {
917 lastmortals = mortals.size ();//D
939 LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D 918 LOG (llevDebug, "%d objects in mortal queue\n", lastmortals);//D
919 }
940} 920}
941 921
942object::object () 922object::object ()
943{ 923{
944 SET_FLAG (this, FLAG_REMOVED); 924 SET_FLAG (this, FLAG_REMOVED);
945 925
946 expmul = 1.0; 926 expmul = 1.0;
947 face = blank_face; 927 face = blank_face;
948 attacked_by_count = -1;
949} 928}
950 929
951object::~object () 930object::~object ()
952{ 931{
953 free_key_values (this); 932 free_key_values (this);
957{ 936{
958 count = ++ob_count; 937 count = ++ob_count;
959 uuid = gen_uuid (); 938 uuid = gen_uuid ();
960 939
961 prev = 0; 940 prev = 0;
962 next = objects; 941 next = object::first;
963 942
964 if (objects) 943 if (object::first)
965 objects->prev = this; 944 object::first->prev = this;
966 945
967 objects = this; 946 object::first = this;
968} 947}
969 948
970void object::unlink () 949void object::unlink ()
971{ 950{
972 //count = 0;//D 951 //count = 0;//D
973 if (!prev && !next) return;//D 952 if (!prev && !next) return;//D
974 953
975 if (this == objects) 954 if (this == object::first)
976 objects = next; 955 object::first = next;
977 956
978 /* Remove this object from the list of used objects */ 957 /* Remove this object from the list of used objects */
979 if (prev) prev->next = next; 958 if (prev) prev->next = next;
980 if (next) next->prev = prev; 959 if (next) next->prev = prev;
981 960
983 next = 0; 962 next = 0;
984} 963}
985 964
986object *object::create () 965object *object::create ()
987{ 966{
988 object *op;
989
990 if (freed.empty ())
991 op = new object; 967 object *op = new object;
992 else
993 {
994 // highly annoying, but the only way to get it stable right now
995 op = freed.back ();
996 freed.pop_back ();
997 op->~object ();
998 new ((void *) op) object;
999 }
1000
1001 op->link (); 968 op->link ();
1002 return op; 969 return op;
1003} 970}
1004 971
1005/* 972/*
1022 989
1023 if (!QUERY_FLAG (this, FLAG_REMOVED)) 990 if (!QUERY_FLAG (this, FLAG_REMOVED))
1024 remove_ob (this); 991 remove_ob (this);
1025 992
1026 SET_FLAG (this, FLAG_FREED); 993 SET_FLAG (this, FLAG_FREED);
1027
1028 //printf ("free(%p,%ld,%ld)\n", this, pticks, count);//D
1029 994
1030 if (more) 995 if (more)
1031 { 996 {
1032 more->free (free_inventory); 997 more->free (free_inventory);
1033 more = 0; 998 more = 0;
1073 op = tmp; 1038 op = tmp;
1074 } 1039 }
1075 } 1040 }
1076 } 1041 }
1077 1042
1043 // clear those pointers that likely might have circular references to us
1078 owner = 0; 1044 owner = 0;
1045 enemy = 0;
1046 attacked_by = 0;
1079 1047
1080 /* Remove object from the active list */ 1048 /* Remove object from the active list */
1081 speed = 0; 1049 speed = 0;
1082 update_ob_speed (this); 1050 update_ob_speed (this);
1083 1051
1095sub_weight (object *op, signed long weight) 1063sub_weight (object *op, signed long weight)
1096{ 1064{
1097 while (op != NULL) 1065 while (op != NULL)
1098 { 1066 {
1099 if (op->type == CONTAINER) 1067 if (op->type == CONTAINER)
1100 {
1101 weight = (signed long) (weight * (100 - op->stats.Str) / 100); 1068 weight = (signed long) (weight * (100 - op->stats.Str) / 100);
1102 } 1069
1103 op->carrying -= weight; 1070 op->carrying -= weight;
1104 op = op->env; 1071 op = op->env;
1105 } 1072 }
1106} 1073}
1107 1074
1115 */ 1082 */
1116 1083
1117void 1084void
1118remove_ob (object *op) 1085remove_ob (object *op)
1119{ 1086{
1087 object *tmp, *last = 0;
1120 object * 1088 object *otmp;
1121 tmp, *
1122 last = NULL;
1123 object *
1124 otmp;
1125 1089
1126 tag_t 1090 tag_t tag;
1127 tag;
1128 int
1129 check_walk_off; 1091 int check_walk_off;
1130 mapstruct * 1092 mapstruct *m;
1131 m;
1132 1093
1133 sint16 1094 sint16 x, y;
1134 x,
1135 y;
1136 1095
1137 if (QUERY_FLAG (op, FLAG_REMOVED)) 1096 if (QUERY_FLAG (op, FLAG_REMOVED))
1138 return; 1097 return;
1139 1098
1140 SET_FLAG (op, FLAG_REMOVED); 1099 SET_FLAG (op, FLAG_REMOVED);
1328 free_object (op); 1287 free_object (op);
1329 return top; 1288 return top;
1330 } 1289 }
1331 } 1290 }
1332 1291
1333 return NULL; 1292 return 0;
1334} 1293}
1335 1294
1336/* 1295/*
1337 * 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
1338 * job preparing multi-part monsters 1297 * job preparing multi-part monsters
1665 remove_ob (tmp); 1624 remove_ob (tmp);
1666 free_object (tmp); 1625 free_object (tmp);
1667 } 1626 }
1668 } 1627 }
1669 1628
1670 tmp1 = arch_to_object (find_archetype (arch_string)); 1629 tmp1 = arch_to_object (archetype::find (arch_string));
1671 1630
1672 tmp1->x = op->x; 1631 tmp1->x = op->x;
1673 tmp1->y = op->y; 1632 tmp1->y = op->y;
1674 insert_ob_in_map (tmp1, op->map, op, 0); 1633 insert_ob_in_map (tmp1, op->map, op, 0);
1675} 1634}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines