--- deliantra/server/common/object.C 2006/12/26 09:37:00 1.88 +++ deliantra/server/common/object.C 2006/12/27 05:22:35 1.94 @@ -780,6 +780,54 @@ next = 0; } +/* + * Remove and free all objects in the inventory of the given object. + * object.c ? + */ +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 + || map->at (x, y).move_block == MOVE_ALL) + { + while (inv) + { + inv->destroy_inv (drop_to_ground); + inv->destroy (); + } + } + else + { /* Put objects in inventory onto this space */ + while (inv) + { + object *op = inv; + + if (op->flag [FLAG_STARTEQUIP] + || op->flag [FLAG_NO_DROP] + || op->type == RUNE + || op->type == TRAP + || op->flag [FLAG_IS_A_TEMPLATE]) + op->destroy (); + else + map->insert (op, x, y); + } + } +} + object *object::create () { object *op = new object; @@ -790,8 +838,6 @@ void object::do_destroy () { - attachable::do_destroy (); - if (flag [FLAG_IS_LINKED]) remove_button_link (this); @@ -804,12 +850,13 @@ if (flag [FLAG_FREED]) return; + set_speed (0); + flag [FLAG_FREED] = 1; - while (inv) - inv->destroy (); + attachable::do_destroy (); - set_speed (0); + destroy_inv (true); unlink (); // hack to ensure that freed objects still have a valid map @@ -849,45 +896,6 @@ contr = 0; } -/* - * Remove and free all objects in the inventory of the given object. - * object.c ? - */ -void -object::destroy_inv (bool drop_to_ground) -{ - /* 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) - { - while (inv) - inv->destroy (); - } - else - { /* Put objects in inventory onto this space */ - while (inv) - { - object *op = inv; - - if (op->flag [FLAG_STARTEQUIP] - || op->flag [FLAG_NO_DROP] - || op->type == RUNE - || op->type == TRAP - || 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 */ - } - } - } -} - void object::destroy (bool destroy_inventory) { @@ -895,7 +903,7 @@ return; if (destroy_inventory) - destroy_inv (true); + destroy_inv (false); attachable::destroy (); } @@ -1018,7 +1026,7 @@ int check_walk_off = !flag [FLAG_NO_APPLY]; - for (tmp = GET_MAP_OB (map, x, y); tmp; tmp = tmp->above) + for (tmp = map->at (x, y).bot; tmp; tmp = tmp->above) { /* No point updating the players look faces if he is the object * being removed. @@ -1114,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; @@ -1443,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 @@ -1450,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) { @@ -1724,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) {