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.220 by root, Thu Apr 24 00:30:52 2008 UTC vs.
Revision 1.227 by root, Sat May 3 09:04:17 2008 UTC

603 } 603 }
604 604
605 op->key_values = 0; 605 op->key_values = 0;
606} 606}
607 607
608object & 608/*
609object::operator =(const object &src) 609 * copy_to first frees everything allocated by the dst object,
610 * and then copies the contents of itself into the second
611 * object, allocating what needs to be allocated. Basically, any
612 * data that is malloc'd needs to be re-malloc/copied. Otherwise,
613 * if the first object is freed, the pointers in the new object
614 * will point at garbage.
615 */
616void
617object::copy_to (object *dst)
610{ 618{
611 bool is_freed = flag [FLAG_FREED]; 619 dst->remove ();
612 bool is_removed = flag [FLAG_REMOVED];
613
614 *(object_copy *)this = src; 620 *(object_copy *)dst = *this;
615
616 flag [FLAG_FREED] = is_freed;
617 flag [FLAG_REMOVED] = is_removed; 621 dst->flag [FLAG_REMOVED] = true;
618 622
619 /* Copy over key_values, if any. */ 623 /* Copy over key_values, if any. */
620 if (src.key_values) 624 if (key_values)
621 { 625 {
622 key_value *tail = 0; 626 key_value *tail = 0;
623 key_values = 0; 627 dst->key_values = 0;
624 628
625 for (key_value *i = src.key_values; i; i = i->next) 629 for (key_value *i = key_values; i; i = i->next)
626 { 630 {
627 key_value *new_link = new key_value; 631 key_value *new_link = new key_value;
628 632
629 new_link->next = 0; 633 new_link->next = 0;
630 new_link->key = i->key; 634 new_link->key = i->key;
631 new_link->value = i->value; 635 new_link->value = i->value;
632 636
633 /* Try and be clever here, too. */ 637 /* Try and be clever here, too. */
634 if (!key_values) 638 if (!dst->key_values)
635 { 639 {
636 key_values = new_link; 640 dst->key_values = new_link;
637 tail = new_link; 641 tail = new_link;
638 } 642 }
639 else 643 else
640 { 644 {
641 tail->next = new_link; 645 tail->next = new_link;
642 tail = new_link; 646 tail = new_link;
643 } 647 }
644 } 648 }
645 } 649 }
646}
647
648/*
649 * copy_to first frees everything allocated by the dst object,
650 * and then copies the contents of itself into the second
651 * object, allocating what needs to be allocated. Basically, any
652 * data that is malloc'd needs to be re-malloc/copied. Otherwise,
653 * if the first object is freed, the pointers in the new object
654 * will point at garbage.
655 */
656void
657object::copy_to (object *dst)
658{
659 *dst = *this;
660 650
661 if (speed < 0) 651 if (speed < 0)
662 dst->speed_left -= rndm (); 652 dst->speed_left -= rndm ();
663 653
664 dst->set_speed (dst->speed); 654 dst->set_speed (dst->speed);
686object * 676object *
687object::clone () 677object::clone ()
688{ 678{
689 object *neu = create (); 679 object *neu = create ();
690 copy_to (neu); 680 copy_to (neu);
681 neu->map = map; // not copied by copy_to
691 return neu; 682 return neu;
692} 683}
693 684
694/* 685/*
695 * If an object with the IS_TURNABLE() flag needs to be turned due 686 * If an object with the IS_TURNABLE() flag needs to be turned due
746 * UP_OBJ_FACE: only the objects face has changed. 737 * UP_OBJ_FACE: only the objects face has changed.
747 */ 738 */
748void 739void
749update_object (object *op, int action) 740update_object (object *op, int action)
750{ 741{
751 if (op == NULL) 742 if (!op)
752 { 743 {
753 /* this should never happen */ 744 /* this should never happen */
754 LOG (llevDebug, "update_object() called for NULL object.\n"); 745 LOG (llevError | logBacktrace, "update_object() called for NULL object.\n");
755 return; 746 return;
756 } 747 }
757 748
758 if (op->env) 749 if (!op->is_on_map ())
759 { 750 {
760 /* Animation is currently handled by client, so nothing 751 /* Animation is currently handled by client, so nothing
761 * to do in this case. 752 * to do in this case.
762 */ 753 */
763 return; 754 return;
764 } 755 }
765
766 /* If the map is saving, don't do anything as everything is
767 * going to get freed anyways.
768 */
769 if (!op->map || op->map->in_memory == MAP_SAVING)
770 return;
771 756
772 /* make sure the object is within map boundaries */ 757 /* make sure the object is within map boundaries */
773 if (op->x < 0 || op->x >= op->map->width || op->y < 0 || op->y >= op->map->height) 758 if (op->x < 0 || op->x >= op->map->width || op->y < 0 || op->y >= op->map->height)
774 { 759 {
775 LOG (llevError, "update_object() called for object out of map!\n"); 760 LOG (llevError, "update_object() called for object out of map!\n");
965 object *op = new object; 950 object *op = new object;
966 op->link (); 951 op->link ();
967 return op; 952 return op;
968} 953}
969 954
955static struct freed_map : maptile
956{
957 freed_map ()
958 {
959 path = "<freed objects map>";
960 name = "/internal/freed_objects_map";
961 width = 3;
962 height = 3;
963 nodrop = 1;
964
965 alloc ();
966 in_memory = MAP_ACTIVE;
967 }
968} freed_map; // freed objects are moved here to avoid crashes
969
970void 970void
971object::do_destroy () 971object::do_destroy ()
972{ 972{
973 if (flag [FLAG_IS_LINKED]) 973 if (flag [FLAG_IS_LINKED])
974 remove_button_link (this); 974 remove_button_link (this);
984 unlink (); 984 unlink ();
985 985
986 flag [FLAG_FREED] = 1; 986 flag [FLAG_FREED] = 1;
987 987
988 // hack to ensure that freed objects still have a valid map 988 // hack to ensure that freed objects still have a valid map
989 {
990 static maptile *freed_map; // freed objects are moved here to avoid crashes
991
992 if (!freed_map)
993 {
994 freed_map = new maptile;
995
996 freed_map->path = "<freed objects map>";
997 freed_map->name = "/internal/freed_objects_map";
998 freed_map->width = 3;
999 freed_map->height = 3;
1000 freed_map->nodrop = 1;
1001
1002 freed_map->alloc ();
1003 freed_map->in_memory = MAP_ACTIVE;
1004 }
1005
1006 map = freed_map; 989 map = &freed_map;
1007 x = 1; 990 x = 1;
1008 y = 1; 991 y = 1;
1009 }
1010 992
1011 if (more) 993 if (more)
1012 { 994 {
1013 more->destroy (); 995 more->destroy ();
1014 more = 0; 996 more = 0;
1031 1013
1032 if (!is_head () && !head->destroyed ()) 1014 if (!is_head () && !head->destroyed ())
1033 { 1015 {
1034 LOG (llevError | logBacktrace, "tried to destroy the tail of an object"); 1016 LOG (llevError | logBacktrace, "tried to destroy the tail of an object");
1035 head->destroy (destroy_inventory); 1017 head->destroy (destroy_inventory);
1018 return;
1036 } 1019 }
1037 1020
1038 destroy_inv (!destroy_inventory); 1021 destroy_inv (!destroy_inventory);
1039 1022
1040 if (is_head ()) 1023 if (is_head ())
1073 * In this case, the object to be removed is in someones 1056 * In this case, the object to be removed is in someones
1074 * inventory. 1057 * inventory.
1075 */ 1058 */
1076 if (env) 1059 if (env)
1077 { 1060 {
1061 flag [FLAG_REMOVED] = false; // hack around the issue of visible_to checking flag_removed
1078 if (object *pl = visible_to ()) 1062 if (object *pl = visible_to ())
1079 esrv_del_item (pl->contr, count); 1063 esrv_del_item (pl->contr, count);
1064 flag [FLAG_REMOVED] = true; // hack around the issue of visible_to checking flag_removed
1080 1065
1081 adjust_weight (env, -total_weight ()); 1066 adjust_weight (env, -total_weight ());
1082 1067
1083 *(above ? &above->below : &env->inv) = below; 1068 *(above ? &above->below : &env->inv) = below;
1084 1069
1167 * appropriately. 1152 * appropriately.
1168 */ 1153 */
1169 pl->close_container (); 1154 pl->close_container ();
1170 1155
1171 //TODO: the floorbox prev/next might need updating 1156 //TODO: the floorbox prev/next might need updating
1172 esrv_del_item (pl->contr, count); 1157 //esrv_del_item (pl->contr, count);
1158 //TODO: update floorbox to preserve ordering
1159 if (pl->contr->ns)
1160 pl->contr->ns->floorbox_update ();
1173 } 1161 }
1174 1162
1175 for (tmp = ms.bot; tmp; tmp = tmp->above) 1163 for (tmp = ms.bot; tmp; tmp = tmp->above)
1176 { 1164 {
1177 /* No point updating the players look faces if he is the object 1165 /* No point updating the players look faces if he is the object
1475 1463
1476 op->map->dirty = true; 1464 op->map->dirty = true;
1477 1465
1478 if (object *pl = ms.player ()) 1466 if (object *pl = ms.player ())
1479 //TODO: the floorbox prev/next might need updating 1467 //TODO: the floorbox prev/next might need updating
1480 esrv_send_item (pl, op); 1468 //esrv_send_item (pl, op);
1469 //TODO: update floorbox to preserve ordering
1470 if (pl->contr->ns)
1471 pl->contr->ns->floorbox_update ();
1481 1472
1482 /* If this object glows, it may affect lighting conditions that are 1473 /* If this object glows, it may affect lighting conditions that are
1483 * visible to others on this map. But update_all_los is really 1474 * visible to others on this map. But update_all_los is really
1484 * an inefficient way to do this, as it means los for all players 1475 * an inefficient way to do this, as it means los for all players
1485 * on the map will get recalculated. The players could very well 1476 * on the map will get recalculated. The players could very well
2332 * create clone from object to another 2323 * create clone from object to another
2333 */ 2324 */
2334object * 2325object *
2335object_create_clone (object *asrc) 2326object_create_clone (object *asrc)
2336{ 2327{
2337 object *dst = 0, *tmp, *src, *prev, *item; 2328 object *dst = 0;
2338 2329
2339 if (!asrc) 2330 if (!asrc)
2340 return 0; 2331 return 0;
2341 2332
2342 src = asrc->head_ (); 2333 object *src = asrc->head_ ();
2343 2334
2344 prev = 0; 2335 object *prev = 0;
2345 for (object *part = src; part; part = part->more) 2336 for (object *part = src; part; part = part->more)
2346 { 2337 {
2347 tmp = part->clone (); 2338 object *tmp = part->clone ();
2339
2348 tmp->x -= src->x; 2340 tmp->x -= src->x;
2349 tmp->y -= src->y; 2341 tmp->y -= src->y;
2350 2342
2351 if (!part->head) 2343 if (!part->head)
2352 { 2344 {
2362 prev->more = tmp; 2354 prev->more = tmp;
2363 2355
2364 prev = tmp; 2356 prev = tmp;
2365 } 2357 }
2366 2358
2367 for (item = src->inv; item; item = item->below) 2359 for (object *item = src->inv; item; item = item->below)
2368 insert_ob_in_ob (object_create_clone (item), dst); 2360 insert_ob_in_ob (object_create_clone (item), dst);
2369 2361
2370 return dst; 2362 return dst;
2371} 2363}
2372 2364

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines