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.221 by root, Thu Apr 24 12:06:01 2008 UTC vs.
Revision 1.226 by root, Sat May 3 08:50:30 2008 UTC

606} 606}
607 607
608object & 608object &
609object::operator =(const object &src) 609object::operator =(const object &src)
610{ 610{
611 bool is_freed = flag [FLAG_FREED]; 611 remove ();
612 bool is_removed = flag [FLAG_REMOVED];
613 612
614 *(object_copy *)this = src; 613 *(object_copy *)this = src;
615 614
616 flag [FLAG_FREED] = is_freed;
617 flag [FLAG_REMOVED] = is_removed; 615 flag [FLAG_REMOVED] = true;
618 616
619 /* Copy over key_values, if any. */ 617 /* Copy over key_values, if any. */
620 if (src.key_values) 618 if (src.key_values)
621 { 619 {
622 key_value *tail = 0; 620 key_value *tail = 0;
686object * 684object *
687object::clone () 685object::clone ()
688{ 686{
689 object *neu = create (); 687 object *neu = create ();
690 copy_to (neu); 688 copy_to (neu);
689 neu->map = map; // not copied by copy_to
691 return neu; 690 return neu;
692} 691}
693 692
694/* 693/*
695 * If an object with the IS_TURNABLE() flag needs to be turned due 694 * If an object with the IS_TURNABLE() flag needs to be turned due
746 * UP_OBJ_FACE: only the objects face has changed. 745 * UP_OBJ_FACE: only the objects face has changed.
747 */ 746 */
748void 747void
749update_object (object *op, int action) 748update_object (object *op, int action)
750{ 749{
751 if (op == NULL) 750 if (!op)
752 { 751 {
753 /* this should never happen */ 752 /* this should never happen */
754 LOG (llevDebug, "update_object() called for NULL object.\n"); 753 LOG (llevError | logBacktrace, "update_object() called for NULL object.\n");
755 return; 754 return;
756 } 755 }
757 756
758 if (op->env) 757 if (!op->is_on_map ())
759 { 758 {
760 /* Animation is currently handled by client, so nothing 759 /* Animation is currently handled by client, so nothing
761 * to do in this case. 760 * to do in this case.
762 */ 761 */
763 return; 762 return;
764 } 763 }
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 764
772 /* make sure the object is within map boundaries */ 765 /* 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) 766 if (op->x < 0 || op->x >= op->map->width || op->y < 0 || op->y >= op->map->height)
774 { 767 {
775 LOG (llevError, "update_object() called for object out of map!\n"); 768 LOG (llevError, "update_object() called for object out of map!\n");
965 object *op = new object; 958 object *op = new object;
966 op->link (); 959 op->link ();
967 return op; 960 return op;
968} 961}
969 962
963static struct freed_map : maptile
964{
965 freed_map ()
966 {
967 path = "<freed objects map>";
968 name = "/internal/freed_objects_map";
969 width = 3;
970 height = 3;
971 nodrop = 1;
972
973 alloc ();
974 in_memory = MAP_ACTIVE;
975 }
976} freed_map; // freed objects are moved here to avoid crashes
977
970void 978void
971object::do_destroy () 979object::do_destroy ()
972{ 980{
973 if (flag [FLAG_IS_LINKED]) 981 if (flag [FLAG_IS_LINKED])
974 remove_button_link (this); 982 remove_button_link (this);
984 unlink (); 992 unlink ();
985 993
986 flag [FLAG_FREED] = 1; 994 flag [FLAG_FREED] = 1;
987 995
988 // hack to ensure that freed objects still have a valid map 996 // 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; 997 map = &freed_map;
1007 x = 1; 998 x = 1;
1008 y = 1; 999 y = 1;
1009 }
1010 1000
1011 if (more) 1001 if (more)
1012 { 1002 {
1013 more->destroy (); 1003 more->destroy ();
1014 more = 0; 1004 more = 0;
1031 1021
1032 if (!is_head () && !head->destroyed ()) 1022 if (!is_head () && !head->destroyed ())
1033 { 1023 {
1034 LOG (llevError | logBacktrace, "tried to destroy the tail of an object"); 1024 LOG (llevError | logBacktrace, "tried to destroy the tail of an object");
1035 head->destroy (destroy_inventory); 1025 head->destroy (destroy_inventory);
1026 return;
1036 } 1027 }
1037 1028
1038 destroy_inv (!destroy_inventory); 1029 destroy_inv (!destroy_inventory);
1039 1030
1040 if (is_head ()) 1031 if (is_head ())
1169 * appropriately. 1160 * appropriately.
1170 */ 1161 */
1171 pl->close_container (); 1162 pl->close_container ();
1172 1163
1173 //TODO: the floorbox prev/next might need updating 1164 //TODO: the floorbox prev/next might need updating
1174 esrv_del_item (pl->contr, count); 1165 //esrv_del_item (pl->contr, count);
1166 //TODO: update floorbox to preserve ordering
1167 if (pl->contr->ns)
1168 pl->contr->ns->floorbox_update ();
1175 } 1169 }
1176 1170
1177 for (tmp = ms.bot; tmp; tmp = tmp->above) 1171 for (tmp = ms.bot; tmp; tmp = tmp->above)
1178 { 1172 {
1179 /* No point updating the players look faces if he is the object 1173 /* No point updating the players look faces if he is the object
1477 1471
1478 op->map->dirty = true; 1472 op->map->dirty = true;
1479 1473
1480 if (object *pl = ms.player ()) 1474 if (object *pl = ms.player ())
1481 //TODO: the floorbox prev/next might need updating 1475 //TODO: the floorbox prev/next might need updating
1482 esrv_send_item (pl, op); 1476 //esrv_send_item (pl, op);
1477 //TODO: update floorbox to preserve ordering
1478 if (pl->contr->ns)
1479 pl->contr->ns->floorbox_update ();
1483 1480
1484 /* If this object glows, it may affect lighting conditions that are 1481 /* If this object glows, it may affect lighting conditions that are
1485 * visible to others on this map. But update_all_los is really 1482 * visible to others on this map. But update_all_los is really
1486 * an inefficient way to do this, as it means los for all players 1483 * an inefficient way to do this, as it means los for all players
1487 * on the map will get recalculated. The players could very well 1484 * on the map will get recalculated. The players could very well
2334 * create clone from object to another 2331 * create clone from object to another
2335 */ 2332 */
2336object * 2333object *
2337object_create_clone (object *asrc) 2334object_create_clone (object *asrc)
2338{ 2335{
2339 object *dst = 0, *tmp, *src, *prev, *item; 2336 object *dst = 0;
2340 2337
2341 if (!asrc) 2338 if (!asrc)
2342 return 0; 2339 return 0;
2343 2340
2344 src = asrc->head_ (); 2341 object *src = asrc->head_ ();
2345 2342
2346 prev = 0; 2343 object *prev = 0;
2347 for (object *part = src; part; part = part->more) 2344 for (object *part = src; part; part = part->more)
2348 { 2345 {
2349 tmp = part->clone (); 2346 object *tmp = part->clone ();
2347
2350 tmp->x -= src->x; 2348 tmp->x -= src->x;
2351 tmp->y -= src->y; 2349 tmp->y -= src->y;
2352 2350
2353 if (!part->head) 2351 if (!part->head)
2354 { 2352 {
2364 prev->more = tmp; 2362 prev->more = tmp;
2365 2363
2366 prev = tmp; 2364 prev = tmp;
2367 } 2365 }
2368 2366
2369 for (item = src->inv; item; item = item->below) 2367 for (object *item = src->inv; item; item = item->below)
2370 insert_ob_in_ob (object_create_clone (item), dst); 2368 insert_ob_in_ob (object_create_clone (item), dst);
2371 2369
2372 return dst; 2370 return dst;
2373} 2371}
2374 2372

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines