--- deliantra/server/common/object.C 2008/05/17 00:17:02 1.243 +++ deliantra/server/common/object.C 2008/08/31 01:17:11 1.254 @@ -188,16 +188,9 @@ || ob1->name != ob2->name) return 0; - // some objects are unmergable - if (!ob1->nrof || !ob2->nrof) - return 0; - - /* Do not merge objects if nrof would overflow. First part checks - * for unsigned overflow (2c), second part checks whether the result - * would fit into a 32 bit signed int, which is often used to hold - * nrof values. - */ - if (~ob1->nrof < ob2->nrof || ob1->nrof + ob2->nrof > (1UL << 31)) + /* Do not merge objects if nrof would overflow, assume nrof + * is always 0 .. 2**31-1 */ + if (ob1->nrof > 0x7fffffff - ob2->nrof) return 0; /* If the objects have been identified, set the BEEN_APPLIED flag. @@ -351,7 +344,8 @@ // maybe there is a player standing on the same mapspace // this will catch the case where "this" is a player if (object *pl = ms ().player ()) - if (!pl->container || this == pl->container) + if ((!pl->container && pl->contr->ns && !pl->contr->ns->update_look) + || this == pl->container) return pl; } } @@ -775,7 +769,7 @@ || (m.move_off | op->move_off ) != m.move_off || (m.move_slow | op->move_slow) != m.move_slow /* This isn't perfect, but I don't expect a lot of objects to - * to have move_allow right now. + * have move_allow right now. */ || ((m.move_block | op->move_block) & ~op->move_allow) != m.move_block || 1) // the above is not strong enough a test to skip updating. los maybe? TODO (Schmorp) @@ -915,10 +909,7 @@ || ms ().move_block == MOVE_ALL) { while (inv) - { - inv->destroy_inv (false); - inv->destroy (); - } + inv->destroy (true); } else { /* Put objects in inventory onto this space */ @@ -1123,6 +1114,8 @@ above = 0; below = 0; + ms.flags_ = 0; + if (map->in_memory == MAP_SAVING) return; @@ -1164,13 +1157,6 @@ last = tmp; } - /* last == NULL if there are no objects on this space */ - //TODO: this makes little sense, why only update the topmost object? - if (!last) - map->at (x, y).flags_ = 0; - else - update_object (last, UP_OBJ_REMOVE); - if (flag [FLAG_BLOCKSVIEW] || glow_radius) update_all_los (map, x, y); } @@ -1243,6 +1229,8 @@ object * insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y) { + op->remove (); + for (object *tmp = op->head_ (); tmp; tmp = tmp->more) { tmp->x = x + tmp->arch->x; @@ -1275,7 +1263,23 @@ object * insert_ob_in_map (object *op, maptile *m, object *originator, int flag) { - op->remove (); + if (op->is_on_map ()) + { + LOG (llevError, "insert_ob_in_map called for object already on map"); + abort (); + } + + if (op->env) + { + LOG (llevError, "insert_ob_in_map called for object in an inventory (proceeding)"); + op->remove (); + } + + if (op->face && !face_info (op->face))//D TODO: remove soon + {//D + LOG (llevError | logBacktrace, "op->face out of bounds: %s", op->debug_desc ());//D + op->face = 1;//D + }//D /* Ideally, the caller figures this out. However, it complicates a lot * of areas of callers (eg, anything that uses find_free_spot would now @@ -1525,11 +1529,10 @@ nr = min (nr, nrof); - nrof -= nr; - - if (nrof) + if (nrof > nr) { - adjust_weight (env, -weight * nr); // carrying == 0 + nrof -= nr; + adjust_weight (env, -weight * max (1, nr)); // carrying == 0 if (object *pl = visible_to ()) esrv_update_item (UPD_NROF, pl, this); @@ -1538,7 +1541,7 @@ } else { - destroy (1); + destroy (); return false; } }