--- deliantra/server/common/object.C 2006/09/17 16:21:53 1.51 +++ deliantra/server/common/object.C 2006/12/03 02:46:33 1.57 @@ -376,82 +376,15 @@ * The result of the dump is stored in the static global errmsg array. */ -void -dump_object2 (object *op) -{ - errmsg[0] = 0; - return; - //TODO//D#d# -#if 0 - char *cp; - -/* object *tmp;*/ - - if (op->arch != NULL) - { - strcat (errmsg, "arch "); - strcat (errmsg, op->arch->name ? op->arch->name : "(null)"); - strcat (errmsg, "\n"); - if ((cp = get_ob_diff (op, &empty_archetype->clone)) != NULL) - strcat (errmsg, cp); -# if 0 - /* Don't dump player diffs - they are too long, mostly meaningless, and - * will overflow the buffer. - * Changed so that we don't dump inventory either. This may - * also overflow the buffer. - */ - if (op->type != PLAYER && (cp = get_ob_diff (op, &empty_archetype->clone)) != NULL) - strcat (errmsg, cp); - for (tmp = op->inv; tmp; tmp = tmp->below) - dump_object2 (tmp); -# endif - strcat (errmsg, "end\n"); - } - else - { - strcat (errmsg, "Object "); - if (op->name == NULL) - strcat (errmsg, "(null)"); - else - strcat (errmsg, op->name); - strcat (errmsg, "\n"); -# if 0 - if ((cp = get_ob_diff (op, &empty_archetype->clone)) != NULL) - strcat (errmsg, cp); - for (tmp = op->inv; tmp; tmp = tmp->below) - dump_object2 (tmp); -# endif - strcat (errmsg, "end\n"); - } -#endif -} - -/* - * Dumps an object. Returns output in the static global errmsg array. - */ - -void +char * dump_object (object *op) { - if (op == NULL) - { - strcpy (errmsg, "[NULL pointer]"); - return; - } - errmsg[0] = '\0'; - dump_object2 (op); -} - -void -dump_all_objects (void) -{ - object *op; + if (!op) + return strdup ("[NULLOBJ]"); - for (op = object::first; op != NULL; op = op->next) - { - dump_object (op); - fprintf (logfile, "Object %s\n", errmsg); - } + object_freezer freezer; + save_object (freezer, op, 3); + return freezer.as_string (); } /* @@ -481,13 +414,11 @@ object * find_object (tag_t i) { - object *op; - - for (op = object::first; op != NULL; op = op->next) + for (object *op = object::first; op; op = op->next) if (op->count == i) - break; + return op; - return op; + return 0; } /* @@ -974,10 +905,10 @@ * The object must have been removed by remove_ob() first for * this function to succeed. * - * If free_inventory is set, free inventory as well. Else drop items in + * If destroy_inventory is set, free inventory as well. Else drop items in * inventory to the ground. */ -void object::free (bool free_inventory) +void object::destroy (bool destroy_inventory) { if (QUERY_FLAG (this, FLAG_FREED)) return; @@ -992,7 +923,7 @@ if (more) { - more->free (free_inventory); + more->destroy (destroy_inventory); more = 0; } @@ -1002,14 +933,14 @@ * if some form of movement is allowed, let objects * drop on that space. */ - if (free_inventory || !map || map->in_memory != MAP_IN_MEMORY || GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL) + if (destroy_inventory || !map || map->in_memory != MAP_IN_MEMORY || GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL) { object *op = inv; while (op) { object *tmp = op->below; - op->free (free_inventory); + op->destroy (destroy_inventory); op = tmp; } } @@ -1038,11 +969,34 @@ } } + // hack to ensure that freed objects still have a valid map + { + static maptile *freed_map; // freed objects are moved here to avoid crashes + + if (!freed_map) + { + freed_map = new maptile; + + freed_map->name = "/internal/freed_objects_map"; + freed_map->width = 3; + freed_map->height = 3; + + freed_map->allocate (); + } + + map = freed_map; + x = 1; + y = 1; + } + // clear those pointers that likely might have circular references to us owner = 0; enemy = 0; attacked_by = 0; + // only relevant for players(?), but make sure of it anyways + contr = 0; + /* Remove object from the active list */ speed = 0; update_ob_speed (this); @@ -1175,11 +1129,13 @@ */ if (GET_MAP_OB (m, x, y) != op) { - dump_object (op); + char *dump = dump_object (op); LOG (llevError, - "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", errmsg); - dump_object (GET_MAP_OB (m, x, y)); - LOG (llevError, "%s\n", errmsg); + "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", dump); + free (dump); + dump = dump_object (GET_MAP_OB (m, x, y)); + LOG (llevError, "%s\n", dump); + free (dump); } SET_MAP_OB (m, x, y, op->above); /* goes on above it. */ @@ -1344,15 +1300,16 @@ if (m == NULL) { - dump_object (op); - LOG (llevError, "Trying to insert in null-map!\n%s\n", errmsg); + char *dump = dump_object (op); + LOG (llevError, "Trying to insert in null-map!\n%s\n", dump); + free (dump); return op; } if (out_of_map (m, op->x, op->y)) { - dump_object (op); - LOG (llevError, "Trying to insert object outside the map.\n%s\n", errmsg); + char *dump = dump_object (op); + LOG (llevError, "Trying to insert object outside the map.\n%s\n", dump); #ifdef MANY_CORES /* Better to catch this here, as otherwise the next use of this object * is likely to cause a crash. Better to find out where it is getting @@ -1360,13 +1317,15 @@ */ abort (); #endif + free (dump); return op; } if (!QUERY_FLAG (op, FLAG_REMOVED)) { - dump_object (op); - LOG (llevError, "Trying to insert (map) inserted object.\n%s\n", errmsg); + char *dump = dump_object (op); + LOG (llevError, "Trying to insert (map) inserted object.\n%s\n", dump); + free (dump); return op; } @@ -1813,15 +1772,17 @@ if (!QUERY_FLAG (op, FLAG_REMOVED)) { - dump_object (op); - LOG (llevError, "Trying to insert (ob) inserted object.\n%s\n", errmsg); + char *dump = dump_object (op); + LOG (llevError, "Trying to insert (ob) inserted object.\n%s\n", dump); + free (dump); return op; } if (where == NULL) { - dump_object (op); - LOG (llevError, "Trying to put object in NULL.\n%s\n", errmsg); + char *dump = dump_object (op); + LOG (llevError, "Trying to put object in NULL.\n%s\n", dump); + free (dump); return op; }