--- deliantra/server/common/object.C 2006/12/03 02:46:33 1.57 +++ deliantra/server/common/object.C 2006/12/11 23:35:37 1.62 @@ -106,7 +106,7 @@ uuid.seq = uid; write_uuid (); - LOG (llevDebug, "read UID: %lld\n", uid); + LOG (llevDebug, "read UID: %" PRId64 "\n", uid); fclose (fp); } @@ -555,6 +555,7 @@ if (is_freed) SET_FLAG (op, FLAG_FREED); + if (is_removed) SET_FLAG (op, FLAG_REMOVED); @@ -806,6 +807,7 @@ if ((move_slow | op->move_slow) != move_slow) update_now = 1; } + /* if the object is being removed, we can't make intelligent * decisions, because remove_ob can't really pass the object * that is being removed. @@ -841,14 +843,6 @@ delete *i; mortals.erase (i); } - - static int lastmortals = 0;//D - - if (mortals.size() != lastmortals && lastmortals > 100)//D - { - lastmortals = mortals.size ();//D - LOG (llevDebug, "%d objects in mortal queue\n", lastmortals);//D - } } object::object () @@ -1010,7 +1004,6 @@ * sub_weight() recursively (outwards) subtracts a number from the * weight of an object (and what is carried by it's environment(s)). */ - void sub_weight (object *op, signed long weight) { @@ -1032,139 +1025,116 @@ * the previous environment. * Beware: This function is called from the editor as well! */ - void -remove_ob (object *op) +object::remove () { object *tmp, *last = 0; object *otmp; int check_walk_off; - maptile *m; - sint16 x, y; - - if (QUERY_FLAG (op, FLAG_REMOVED)) + if (QUERY_FLAG (this, FLAG_REMOVED)) return; - SET_FLAG (op, FLAG_REMOVED); + SET_FLAG (this, FLAG_REMOVED); - if (op->more != NULL) - remove_ob (op->more); + if (more) + more->remove (); /* * In this case, the object to be removed is in someones * inventory. */ - if (op->env != NULL) + if (env) { - if (op->nrof) - sub_weight (op->env, op->weight * op->nrof); + if (nrof) + sub_weight (env, weight * nrof); else - sub_weight (op->env, op->weight + op->carrying); + sub_weight (env, weight + carrying); /* NO_FIX_PLAYER is set when a great many changes are being * made to players inventory. If set, avoiding the call * to save cpu time. */ - if ((otmp = is_player_inv (op->env)) != NULL && otmp->contr && !QUERY_FLAG (otmp, FLAG_NO_FIX_PLAYER)) + if ((otmp = is_player_inv (env)) != NULL && otmp->contr && !QUERY_FLAG (otmp, FLAG_NO_FIX_PLAYER)) fix_player (otmp); - if (op->above != NULL) - op->above->below = op->below; + if (above != NULL) + above->below = below; else - op->env->inv = op->below; + env->inv = below; - if (op->below != NULL) - op->below->above = op->above; + if (below != NULL) + below->above = above; /* we set up values so that it could be inserted into * the map, but we don't actually do that - it is up * to the caller to decide what we want to do. */ - op->x = op->env->x, op->y = op->env->y; - op->map = op->env->map; - op->above = NULL, op->below = NULL; - op->env = NULL; + x = env->x, y = env->y; + map = env->map; + above = 0, below = 0; + env = 0; } - else if (op->map) + else if (map) { - x = op->x; - y = op->y; - m = get_map_from_coord (op->map, &x, &y); - - if (!m) - { - LOG (llevError, "remove_ob called when object was on map but appears to not be within valid coordinates? %s (%d,%d)\n", - op->map->path, op->x, op->y); - /* in old days, we used to set x and y to 0 and continue. - * it seems if we get into this case, something is probablye - * screwed up and should be fixed. - */ - abort (); - } - - if (op->map != m) - LOG (llevDebug, "remove_ob: Object not really on map it claimed to be on? %s != %s, %d,%d != %d,%d\n", - op->map->path, m->path, op->x, op->y, x, y); - /* Re did the following section of code - it looks like it had * lots of logic for things we no longer care about */ /* link the object above us */ - if (op->above) - op->above->below = op->below; + if (above) + above->below = below; else - SET_MAP_TOP (m, x, y, op->below); /* we were top, set new top */ + SET_MAP_TOP (map, x, y, below); /* we were top, set new top */ /* Relink the object below us, if there is one */ - if (op->below) - op->below->above = op->above; + if (below) + below->above = above; else { /* Nothing below, which means we need to relink map object for this space * use translated coordinates in case some oddness with map tiling is * evident */ - if (GET_MAP_OB (m, x, y) != op) + if (GET_MAP_OB (map, x, y) != this) { - char *dump = dump_object (op); + 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 (m, x, y)); + dump = dump_object (GET_MAP_OB (map, x, y)); LOG (llevError, "%s\n", dump); free (dump); } - SET_MAP_OB (m, x, y, op->above); /* goes on above it. */ + SET_MAP_OB (map, x, y, above); /* goes on above it. */ } - op->above = 0; - op->below = 0; + above = 0; + below = 0; - if (op->map->in_memory == MAP_SAVING) + if (map->in_memory == MAP_SAVING) return; - check_walk_off = !QUERY_FLAG (op, FLAG_NO_APPLY); + check_walk_off = !QUERY_FLAG (this, FLAG_NO_APPLY); - for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) + for (tmp = GET_MAP_OB (map, x, y); tmp; tmp = tmp->above) { /* No point updating the players look faces if he is the object * being removed. */ - if (tmp->type == PLAYER && tmp != op) + if (tmp->type == PLAYER && tmp != this) { /* If a container that the player is currently using somehow gets * removed (most likely destroyed), update the player view * appropriately. */ - if (tmp->container == op) + if (tmp->container == this) { - CLEAR_FLAG (op, FLAG_APPLIED); - tmp->container = NULL; + CLEAR_FLAG (this, FLAG_APPLIED); + tmp->container = 0; } tmp->contr->socket.update_look = 1; @@ -1172,39 +1142,39 @@ /* See if player moving off should effect something */ if (check_walk_off - && ((op->move_type & tmp->move_off) - && (op->move_type & ~tmp->move_off & ~tmp->move_block) == 0)) + && ((move_type & tmp->move_off) + && (move_type & ~tmp->move_off & ~tmp->move_block) == 0)) { - move_apply (tmp, op, NULL); + move_apply (tmp, this, 0); - if (op->destroyed ()) + if (destroyed ()) LOG (llevError, "BUG: remove_ob(): name %s, destroyed leaving object\n", tmp->debug_desc ()); } /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */ if (tmp->above == tmp) - tmp->above = NULL; + tmp->above = 0; last = tmp; } /* last == NULL of there are no objects on this space */ - if (last == NULL) + if (!last) { /* set P_NEED_UPDATE, otherwise update_position will complain. In theory, * we could preserve the flags (GET_MAP_FLAGS), but update_position figures * those out anyways, and if there are any flags set right now, they won't * be correct anyways. */ - SET_MAP_FLAGS (op->map, op->x, op->y, P_NEED_UPDATE); - update_position (op->map, op->x, op->y); + SET_MAP_FLAGS (map, x, y, P_NEED_UPDATE); + update_position (map, x, y); } else update_object (last, UP_OBJ_REMOVE); - if (QUERY_FLAG (op, FLAG_BLOCKSVIEW) || (op->glow_radius != 0)) - update_all_los (op->map, op->x, op->y); + if (QUERY_FLAG (this, FLAG_BLOCKSVIEW) || glow_radius) + update_all_los (map, x, y); } } @@ -1749,36 +1719,10 @@ } } -/* - * insert_ob_in_ob(op,environment): - * This function inserts the object op in the linked list - * inside the object environment. - * - * Eneq(@csd.uu.se): Altered insert_ob_in_ob to make things picked up enter - * the inventory at the last position or next to other objects of the same - * type. - * Frank: Now sorted by type, archetype and magic! - * - * The function returns now pointer to inserted item, and return value can - * be != op, if items are merged. -Tero - */ - object * insert_ob_in_ob (object *op, object *where) { - object * - tmp, * - otmp; - - if (!QUERY_FLAG (op, FLAG_REMOVED)) - { - char *dump = dump_object (op); - LOG (llevError, "Trying to insert (ob) inserted object.\n%s\n", dump); - free (dump); - return op; - } - - if (where == NULL) + if (!where) { char *dump = dump_object (op); LOG (llevError, "Trying to put object in NULL.\n%s\n", dump); @@ -1788,10 +1732,30 @@ if (where->head) { - LOG (llevDebug, "Warning: Tried to insert object wrong part of multipart object.\n"); + LOG (llevDebug, "Warning: Tried to insert object into wrong part of multipart object.\n"); where = where->head; } + return where->insert (op); +} + +/* + * env->insert (op) + * This function inserts the object op in the linked list + * inside the object environment. + * + * The function returns now pointer to inserted item, and return value can + * be != op, if items are merged. -Tero + */ + +object * +object::insert (object *op) +{ + object *tmp, *otmp; + + if (!QUERY_FLAG (op, FLAG_REMOVED)) + op->remove (); + if (op->more) { LOG (llevError, "Tried to insert multipart object %s (%d)\n", &op->name, op->count); @@ -1802,7 +1766,7 @@ CLEAR_FLAG (op, FLAG_REMOVED); if (op->nrof) { - for (tmp = where->inv; tmp != NULL; tmp = tmp->below) + for (tmp = inv; tmp != NULL; tmp = tmp->below) if (CAN_MERGE (tmp, op)) { /* return the original object and remove inserted object @@ -1811,11 +1775,11 @@ /* Weight handling gets pretty funky. Since we are adding to * tmp->nrof, we need to increase the weight. */ - add_weight (where, op->weight * op->nrof); + add_weight (this, op->weight * op->nrof); SET_FLAG (op, FLAG_REMOVED); - free_object (op); /* free the inserted object */ + op->destroy (); /* free the inserted object */ op = tmp; - remove_ob (op); /* and fix old object's links */ + op->remove (); /* and fix old object's links */ CLEAR_FLAG (op, FLAG_REMOVED); break; } @@ -1826,45 +1790,44 @@ * the weight, so we need to add it in again, since we actually do * the linking below */ - add_weight (where, op->weight * op->nrof); + add_weight (this, op->weight * op->nrof); } else - add_weight (where, (op->weight + op->carrying)); + add_weight (this, (op->weight + op->carrying)); - otmp = is_player_inv (where); - if (otmp && otmp->contr != NULL) - { - if (!QUERY_FLAG (otmp, FLAG_NO_FIX_PLAYER)) - fix_player (otmp); - } + otmp = is_player_inv (this); + if (otmp && otmp->contr) + if (!QUERY_FLAG (otmp, FLAG_NO_FIX_PLAYER)) + fix_player (otmp); op->map = NULL; - op->env = where; + op->env = this; op->above = NULL; op->below = NULL; op->x = 0, op->y = 0; /* reset the light list and los of the players on the map */ - if ((op->glow_radius != 0) && where->map) + if ((op->glow_radius != 0) && map) { #ifdef DEBUG_LIGHTS LOG (llevDebug, " insert_ob_in_ob(): got %s to insert in map/op\n", op->name); #endif /* DEBUG_LIGHTS */ - if (MAP_DARKNESS (where->map)) - update_all_los (where->map, where->x, where->y); + if (MAP_DARKNESS (map)) + update_all_los (map, x, y); } /* Client has no idea of ordering so lets not bother ordering it here. * It sure simplifies this function... */ - if (where->inv == NULL) - where->inv = op; + if (!inv) + inv = op; else { - op->below = where->inv; + op->below = inv; op->below->above = op; - where->inv = op; + inv = op; } + return op; } @@ -2563,34 +2526,38 @@ object * object_create_clone (object *asrc) { - object * - dst = NULL, *tmp, *src, *part, *prev, *item; + object *dst = 0, *tmp, *src, *part, *prev, *item; if (!asrc) - return NULL; + return 0; + src = asrc; if (src->head) src = src->head; - prev = NULL; + prev = 0; for (part = src; part; part = part->more) { tmp = get_object (); copy_object (part, tmp); tmp->x -= src->x; tmp->y -= src->y; + if (!part->head) { dst = tmp; - tmp->head = NULL; + tmp->head = 0; } else { tmp->head = dst; } - tmp->more = NULL; + + tmp->more = 0; + if (prev) prev->more = tmp; + prev = tmp; }