--- deliantra/server/common/object.C 2007/01/15 21:06:18 1.116 +++ deliantra/server/common/object.C 2007/01/18 16:19:34 1.117 @@ -901,7 +901,7 @@ * Beware: This function is called from the editor as well! */ void -object::remove () +object::remove_slow () { object *tmp, *last = 0; object *otmp; @@ -959,12 +959,13 @@ } map->dirty = true; + mapspace &ms = this->ms (); /* link the object above us */ if (above) above->below = below; else - map->at (x, y).top = below; /* we were top, set new top */ + ms.top = below; /* we were top, set new top */ /* Relink the object below us, if there is one */ if (below) @@ -976,17 +977,9 @@ * evident */ if (GET_MAP_OB (map, x, y) != this) - { - char *dump = dump_object (this); - LOG (llevError, - "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom?\n%s\n", dump); - free (dump); - dump = dump_object (GET_MAP_OB (map, x, y)); - LOG (llevError, "%s\n", dump); - free (dump); - } + LOG (llevError, "remove_ob: GET_MAP_OB does not return object to be removed even though it appears to be on the bottom? %s\n", debug_desc ()); - map->at (x, y).bot = above; /* goes on above it. */ + ms.bot = above; /* goes on above it. */ } above = 0; @@ -997,7 +990,7 @@ int check_walk_off = !flag [FLAG_NO_APPLY]; - for (tmp = map->at (x, y).bot; tmp; tmp = tmp->above) + for (tmp = ms.bot; tmp; tmp = tmp->above) { /* No point updating the players look faces if he is the object * being removed. @@ -1088,8 +1081,8 @@ } /* - * same as insert_ob_in_map except it handle separate coordinates and do a clean - * job preparing multi-part monsters + * same as insert_ob_in_map except it handles separate coordinates and does a clean + * job preparing multi-part monsters. */ object * insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y) @@ -1127,7 +1120,6 @@ insert_ob_in_map (object *op, maptile *m, object *originator, int flag) { object *tmp, *top, *floor = NULL; - sint16 x, y; if (QUERY_FLAG (op, FLAG_FREED)) { @@ -1135,6 +1127,11 @@ return NULL; } + if (!QUERY_FLAG (op, FLAG_REMOVED)) + LOG (llevError, "Trying to insert already inserted object %s\n", op->debug_desc ()); + + op->remove (); + if (!m) { char *dump = dump_object (op); @@ -1158,36 +1155,9 @@ return op; } - if (!QUERY_FLAG (op, FLAG_REMOVED)) - { - char *dump = dump_object (op); - LOG (llevError, "Trying to insert (map) inserted object.\n%s\n", dump); - free (dump); - return op; - } - - if (op->more) + if (object *more = op->more) { - /* The part may be on a different map. */ - - object *more = op->more; - - /* We really need the caller to normalise coordinates - if - * we set the map, that doesn't work if the location is within - * a map and this is straddling an edge. So only if coordinate - * is clear wrong do we normalise it. - */ - if (OUT_OF_REAL_MAP (more->map, more->x, more->y)) - more->map = get_map_from_coord (m, &more->x, &more->y); - else if (!more->map) - { - /* For backwards compatibility - when not dealing with tiled maps, - * more->map should always point to the parent. - */ - more->map = m; - } - - if (insert_ob_in_map (more, more->map, originator, flag) == NULL) + if (!insert_ob_in_map (more, m, originator, flag)) { if (!op->head) LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); @@ -1202,14 +1172,16 @@ * of areas of callers (eg, anything that uses find_free_spot would now * need extra work */ - op->map = get_map_from_coord (m, &op->x, &op->y); - x = op->x; - y = op->y; + if (!xy_normalise (m, op->x, op->y)) + return 0; + + op->map = m; + mapspace &ms = op->ms (); /* this has to be done after we translate the coordinates. */ if (op->nrof && !(flag & INS_NO_MERGE)) - for (tmp = GET_MAP_OB (op->map, x, y); tmp; tmp = tmp->above) + for (tmp = ms.bot; tmp; tmp = tmp->above) if (object::can_merge (op, tmp)) { op->nrof += tmp->nrof; @@ -1236,15 +1208,17 @@ if (op->below) op->below->above = op; else - op->ms ().bot = op; + ms.bot = op; /* since *below* originator, no need to update top */ originator->below = op; } else { + top = ms.bot; + /* If there are other objects, then */ - if ((!(flag & INS_MAP_LOAD)) && ((top = GET_MAP_OB (op->map, op->x, op->y)) != NULL)) + if ((!(flag & INS_MAP_LOAD)) && top) { object *last = 0; @@ -1260,7 +1234,7 @@ * when lots of spells are cast in one area. Currently, it is presumed * that flying non pickable objects are spell objects. */ - while (top) + for (top = ms.bot; top; top = top->above) { if (QUERY_FLAG (top, FLAG_IS_FLOOR) || QUERY_FLAG (top, FLAG_OVERLAY_FLOOR)) floor = top; @@ -1273,7 +1247,6 @@ } last = top; - top = top->above; } /* Don't want top to be NULL, so set it to the last valid object */ @@ -1290,12 +1263,14 @@ * Need to find the object that in fact blocks view, otherwise * stacking is a bit odd. */ - if (!(flag & INS_ON_TOP) && - (get_map_flags (op->map, 0, op->x, op->y, 0, 0) & P_BLOCKSVIEW) && (op->face && !op->face->visibility)) + if (!(flag & INS_ON_TOP) + && ms.flags () & P_BLOCKSVIEW + && (op->face && !op->face->visibility)) { for (last = top; last != floor; last = last->below) if (QUERY_FLAG (last, FLAG_BLOCKSVIEW) && (last->type != EXIT)) break; + /* Check to see if we found the object that blocks view, * and make sure we have a below pointer for it so that * we can get inserted below this one, which requires we @@ -1307,7 +1282,7 @@ } /* If objects on this space */ if (flag & INS_MAP_LOAD) - top = GET_MAP_TOP (op->map, op->x, op->y); + top = ms.top; if (flag & INS_ABOVE_FLOOR_ONLY) top = floor; @@ -1318,13 +1293,13 @@ /* First object on this space */ if (!top) { - op->above = GET_MAP_OB (op->map, op->x, op->y); + op->above = ms.bot; if (op->above) op->above->below = op; op->below = 0; - op->ms ().bot = op; + ms.bot = op; } else { /* get inserted into the stack above top */ @@ -1338,7 +1313,7 @@ } if (!op->above) - op->ms ().top = op; + ms.top = op; } /* else not INS_BELOW_ORIGINATOR */ if (op->type == PLAYER) @@ -1354,7 +1329,7 @@ * it, so save a few ticks and start from there. */ if (!(flag & INS_MAP_LOAD)) - if (object *pl = op->ms ().player ()) + if (object *pl = ms.player ()) if (pl->contr->ns) pl->contr->ns->floorbox_update (); @@ -2593,10 +2568,10 @@ char info2[256 * 4]; char *p = info; - p += snprintf (p, 512, "{cnt:%d,uuid:<1,%" PRIx64 ">,name:\"%s%s%s\",flags:[%s],type:%d}", + p += snprintf (p, 512, "{cnt:%d,uuid:<1,%" PRIx64 ">,name:\"%s\"%s%s,flags:[%s],type:%d}", count, uuid.seq, &name, - title ? "\",title:" : "", + title ? "\",title:\"" : "", title ? (const char *)title : "", flag_desc (flagdesc, 512), type);