--- deliantra/server/common/object.C 2008/05/07 11:02:50 1.238 +++ deliantra/server/common/object.C 2008/05/18 17:52:53 1.244 @@ -188,6 +188,10 @@ || 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 @@ -208,7 +212,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 +223,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 @@ -480,13 +485,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; } /* @@ -1238,6 +1243,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; @@ -1270,7 +1277,17 @@ 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 (); + } /* Ideally, the caller figures this out. However, it complicates a lot * of areas of callers (eg, anything that uses find_free_spot would now @@ -1312,12 +1329,16 @@ if (flag & INS_BELOW_ORIGINATOR) { - if (originator->map != op->map || originator->x != op->x || originator->y != op->y || !originator->is_on_map ()) + if (originator->map != op->map || originator->x != op->x || originator->y != op->y) { LOG (llevError, "insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n"); abort (); } + if (!originator->is_on_map ()) + LOG (llevDebug | logBacktrace, "insert_ob_in_map(%s) called with INS_BELOW_ORIGINATOR when originator '%s' not on map", + op->debug_desc (), originator->debug_desc ()); + op->above = originator; op->below = originator->below; originator->below = op; @@ -1393,27 +1414,24 @@ if (flag & INS_ABOVE_FLOOR_ONLY) top = floor; - /* Top is the object that our object (op) is going to get inserted above. - */ - - /* no top found, insert on top */ + // insert object above top, or bottom-most if top = 0 if (!top) { - op->above = 0; - op->below = ms.top; - ms.top = op; + op->below = 0; + op->above = ms.bot; + ms.bot = op; - *(op->below ? &op->below->above : &ms.bot) = op; + *(op->above ? &op->above->below : &ms.top) = op; } else - { /* get inserted into the stack above top */ + { op->above = top->above; top->above = op; op->below = top; *(op->above ? &op->above->below : &ms.top) = op; } - } /* else not INS_BELOW_ORIGINATOR */ + } if (op->type == PLAYER) { @@ -2418,12 +2436,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)