--- deliantra/server/common/object.C 2006/12/26 10:14:24 1.90 +++ deliantra/server/common/object.C 2006/12/27 05:42:08 1.95 @@ -787,14 +787,28 @@ void object::destroy_inv (bool drop_to_ground) { + // need to check first, because the checks below might segfault + // as we might be on an invalid mapspace and crossfire code + // is too buggy to ensure that the inventory is empty. + // corollary: if you create arrows etc. with stuff in tis inventory, + // cf will crash below with off-map x and y + if (!inv) + return; + /* Only if the space blocks everything do we not process - * if some form of movement is allowed, let objects * drop on that space. */ - if (!drop_to_ground || !map || map->in_memory != MAP_IN_MEMORY || GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL) + if (!drop_to_ground + || !map + || map->in_memory != MAP_IN_MEMORY + || ms ().move_block == MOVE_ALL) { while (inv) - inv->destroy (); + { + inv->destroy_inv (drop_to_ground); + inv->destroy (); + } } else { /* Put objects in inventory onto this space */ @@ -809,12 +823,7 @@ || op->flag [FLAG_IS_A_TEMPLATE]) op->destroy (); else - { - op->remove (); - op->x = x; - op->y = y; - insert_ob_in_map (op, map, 0, 0); /* Insert in same map as the envir */ - } + map->insert (op, x, y); } } } @@ -841,12 +850,13 @@ if (flag [FLAG_FREED]) return; + set_speed (0); + flag [FLAG_FREED] = 1; attachable::do_destroy (); destroy_inv (true); - set_speed (0); unlink (); // hack to ensure that freed objects still have a valid map @@ -1047,7 +1057,6 @@ if (destroyed ()) LOG (llevError, "BUG: remove_ob(): name %s, destroyed leaving object\n", tmp->debug_desc ()); - LOG (llevError, "BUG: remove_ob(): name %s, destroyed leaving object\n", tmp->debug_desc ()); } /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ @@ -1113,12 +1122,7 @@ object * insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y) { - object *tmp; - - if (op->head) - op = op->head; - - for (tmp = op; tmp; tmp = tmp->more) + for (object *tmp = op->head_ (); tmp; tmp = tmp->more) { tmp->x = x + tmp->arch->clone.x; tmp->y = y + tmp->arch->clone.y; @@ -1442,6 +1446,12 @@ insert_ob_in_map (tmp1, op->map, op, 0); } +object * +object::insert_at (object *where, object *originator, int flags) +{ + where->map->insert (this, where->x, where->y, originator, flags); +} + /* * get_split_ob(ob,nr) splits up ob into two parts. The part which * is returned contains nr objects, and the remaining parts contains @@ -1449,7 +1459,6 @@ * On failure, NULL is returned, and the reason put into the * global static errmsg array. */ - object * get_split_ob (object *orig_ob, uint32 nr) { @@ -1723,7 +1732,6 @@ * object being inserted. insert_ob_in_map may not put new objects * on top. */ - int check_move_on (object *op, object *originator) {