--- deliantra/server/common/object.C 2007/09/12 11:10:09 1.188 +++ deliantra/server/common/object.C 2007/10/15 17:50:27 1.193 @@ -256,13 +256,14 @@ */ if (ob1->inv || ob2->inv) { - /* if one object has inventory but the other doesn't, not equiv */ - if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv)) - return 0; + if (!(ob1->inv && ob2->inv)) + return 0; /* inventories differ in length */ + + if (ob1->inv->below || ob2->inv->below) + return 0; /* more than one object in inv */ - /* Now check to see if the two inventory objects could merge */ if (!object::can_merge (ob1->inv, ob2->inv)) - return 0; + return 0; /* inventory objexts differ */ /* inventory ok - still need to check rest of this object to see * if it is valid. @@ -307,8 +308,17 @@ ob2->optimise (); if (ob1->self || ob2->self) - if (!cfperl_can_merge (ob1, ob2)) - return 0; + { + int k1 = ob1->self ? HvTOTALKEYS (SvRV (ob1->self)) : 0; + int k2 = ob2->self ? HvTOTALKEYS (SvRV (ob2->self)) : 0; + + if (k1 != k2) + return 0; + else if (k1 == 0) + return 1; + else if (!cfperl_can_merge (ob1, ob2)) + return 0; + } } /* Everything passes, must be OK. */ @@ -1292,7 +1302,7 @@ top = ms.bot; /* If there are other objects, then */ - if ((!(flag & INS_MAP_LOAD)) && top) + if (top) { object *last = 0; @@ -1354,8 +1364,6 @@ top = last->below; } } /* If objects on this space */ - if (flag & INS_MAP_LOAD) - top = ms.top; if (flag & INS_ABOVE_FLOOR_ONLY) top = floor; @@ -1398,9 +1406,8 @@ op->map->dirty = true; - if (!(flag & INS_MAP_LOAD)) - if (object *pl = ms.player ()) - pl->contr->ns->floorbox_update (); + if (object *pl = ms.player ()) + pl->contr->ns->floorbox_update (); /* If this object glows, it may affect lighting conditions that are * visible to others on this map. But update_all_los is really @@ -1993,8 +2000,8 @@ int find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop) { - int index = 0, flag; int altern[SIZEOFFREE]; + int index = 0, flag; for (int i = start; i < stop; i++) { @@ -2004,14 +2011,19 @@ continue; mapspace &ms = *pos; - ms.update (); + + if (ms.flags () & P_IS_ALIVE) + continue; /* However, often * ob doesn't have any move type (when used to place exits) * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work. */ if (ob->move_type == 0 && ms.move_block != MOVE_ALL) - continue; + { + altern [index++] = i; + continue; + } /* Basically, if we find a wall on a space, we cut down the search size. * In this way, we won't return spaces that are on another side of a wall.