--- deliantra/server/common/object.C 2008/05/07 19:19:09 1.241 +++ deliantra/server/common/object.C 2008/10/01 16:04:16 1.261 @@ -188,12 +188,9 @@ || ob1->name != ob2->name) 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. @@ -208,7 +205,7 @@ if (QUERY_FLAG (ob2, FLAG_IDENTIFIED)) SET_FLAG (ob2, FLAG_BEEN_APPLIED); - if (ob1->arch->name != ob2->arch->name + if (ob1->arch->archname != ob2->arch->archname || ob1->name != ob2->name || ob1->title != ob2->title || ob1->msg != ob2->msg @@ -219,6 +216,7 @@ || ob1->skill != ob2->skill || ob1->value != ob2->value || ob1->animation_id != ob2->animation_id + || (ob1->face != ob2->face && !ob1->animation_id) // face and animation are dependent on each other || ob1->client_type != ob2->client_type || ob1->materialname != ob2->materialname || ob1->lore != ob2->lore @@ -236,7 +234,6 @@ if ((ob1->flag ^ ob2->flag) .reset (FLAG_INV_LOCKED) - .reset (FLAG_CLIENT_SENT) .reset (FLAG_REMOVED) .any ()) return 0; @@ -346,7 +343,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; } } @@ -480,13 +478,13 @@ find_object_name (const char *str) { shstr_cmp str_ (str); - object *op; - for_all_objects (op) - if (op->name == str_) - break; + if (str_) + for_all_objects (op) + if (op->name == str_) + return op; - return op; + return 0; } /* @@ -640,7 +638,7 @@ if (speed < 0) dst->speed_left -= rndm (); - dst->set_speed (dst->speed); + dst->activate (); } void @@ -770,7 +768,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) @@ -834,6 +832,9 @@ if (active) return; + if (has_active_speed () && flag [FLAG_FREED]) LOG (llevError | logBacktrace, "BUG: tried to activate freed object %s\n", debug_desc ());//D + if (has_active_speed () && flag [FLAG_DEBUG]) LOG (llevError | logBacktrace, "BUG: tried to activate DEBUG object %s\n", debug_desc ());//D temp + if (has_active_speed ()) actives.insert (this); } @@ -910,10 +911,7 @@ || ms ().move_block == MOVE_ALL) { while (inv) - { - inv->destroy_inv (false); - inv->destroy (); - } + inv->destroy (); } else { /* Put objects in inventory onto this space */ @@ -927,7 +925,7 @@ || op->type == TRAP || op->flag [FLAG_IS_A_TEMPLATE] || op->flag [FLAG_DESTROY_ON_DEATH]) - op->destroy (true); + op->destroy (); else map->insert (op, x, y); } @@ -1001,7 +999,7 @@ } void -object::destroy (bool destroy_inventory) +object::destroy () { if (destroyed ()) return; @@ -1009,11 +1007,11 @@ if (!is_head () && !head->destroyed ()) { LOG (llevError | logBacktrace, "tried to destroy the tail of an object"); - head->destroy (destroy_inventory); + head->destroy (); return; } - destroy_inv (!destroy_inventory); + destroy_inv (false); if (is_head ()) if (sound_destroy) @@ -1118,6 +1116,8 @@ above = 0; below = 0; + ms.flags_ = 0; + if (map->in_memory == MAP_SAVING) return; @@ -1159,13 +1159,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); } @@ -1200,7 +1193,7 @@ op->weight = 0; // cancel the addition above op->carrying = 0; // must be 0 already - op->destroy (1); + op->destroy (); return top; } @@ -1238,6 +1231,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; @@ -1272,13 +1267,18 @@ { op->remove (); + if (m == &freed_map)//D TODO: remove soon + {//D + LOG (llevError | logBacktrace, "tries to insret object on freed objects map: %s", op->debug_desc ());//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 * need extra work */ if (!xy_normalise (m, op->x, op->y)) { - op->head_ ()->destroy (1);// remove head_ once all tail object destroyers found + op->head_ ()->destroy ();// remove head_ once all tail object destroyers found return 0; } @@ -1301,7 +1301,7 @@ // but some caller surely breaks when we return tmp // from here :/ op->nrof += tmp->nrof; - tmp->destroy (1); + tmp->destroy (); } CLEAR_FLAG (op, FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */ @@ -1486,7 +1486,7 @@ for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above) if (!strcmp (tmp->arch->archname, arch_string)) /* same archetype */ - tmp->destroy (1); + tmp->destroy (); object *tmp = arch_to_object (archetype::find (arch_string)); @@ -1520,11 +1520,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); @@ -1533,7 +1532,7 @@ } else { - destroy (1); + destroy (); return false; } } @@ -1620,7 +1619,7 @@ adjust_weight (this, op->total_weight ()); - op->destroy (1); + op->destroy (); op = tmp; goto inserted; } @@ -2419,12 +2418,13 @@ char info2[256 * 4]; char *p = info; - p += snprintf (p, 512, "{cnt:%d,uuid:%s,name:\"%s\"%s%s,flags:[%s],type:%d}", + p += snprintf (p, 512, "{cnt:%d,uuid:%s,name:\"%s\"%s%s%s,flags:[%s],type:%d}", count, uuid.c_str (), &name, - title ? "\",title:\"" : "", + title ? ",title:\"" : "", title ? (const char *)title : "", + title ? "\"" : "", flag_desc (flagdesc, 512), type); if (!flag[FLAG_REMOVED] && env)