--- deliantra/server/common/object.C 2006/12/31 18:10:40 1.99 +++ deliantra/server/common/object.C 2007/01/15 21:06:18 1.116 @@ -1,25 +1,26 @@ /* - CrossFire, A Multiplayer game for X-windows - - Copyright (C) 2001 Mark Wedel & Crossfire Development Team - Copyright (C) 1992 Frank Tore Johansen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - The authors can be reached via e-mail at -*/ + * CrossFire, A Multiplayer game for X-windows + * + * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team + * Copyright (C) 2001 Mark Wedel & Crossfire Development Team + * Copyright (C) 1992 Frank Tore Johansen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * The authors can be reached via e-mail at + */ /* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects. sub/add_weight will transcend the environment updating the carrying @@ -38,7 +39,8 @@ static UUID uuid; const uint64 UUID_SKIP = 1<<19; -object *active_objects; /* List of active objects that need to be processed */ +objectvec objects; +activevec actives; short freearr_x[SIZEOFFREE] = { 0, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -3, -3, -3, -3, -2, -1 @@ -392,13 +394,12 @@ /* * Returns the object which has the count-variable equal to the argument. */ - object * find_object (tag_t i) { - for (object *op = object::first; op; op = op->next) - if (op->count == i) - return op; + for_all_objects (op) + if (op->count == i) + return op; return 0; } @@ -408,14 +409,13 @@ * Used only by the patch command, but not all that useful. * Enables features like "patch food 999" */ - object * find_object_name (const char *str) { shstr_cmp str_ (str); object *op; - for (op = object::first; op != NULL; op = op->next) + for_all_objects (op) if (op->name == str_) break; @@ -662,8 +662,6 @@ update_object (op->more, action); } -object *object::first; - object::object () { SET_FLAG (this, FLAG_REMOVED); @@ -677,57 +675,34 @@ free_key_values (this); } +static int object_count; + void object::link () { - count = ++ob_count; + assert (!index);//D uuid = gen_uuid (); + count = ++object_count; - prev = 0; - next = object::first; - - if (object::first) - object::first->prev = this; - - object::first = this; + refcnt_inc (); + objects.insert (this); } void object::unlink () { - if (this == object::first) - object::first = next; - - /* Remove this object from the list of used objects */ - if (prev) prev->next = next; - if (next) next->prev = prev; - - prev = 0; - next = 0; -} - -bool -object::active () const -{ - return active_next || active_prev || this == active_objects; + assert (index);//D + objects.erase (this); + refcnt_dec (); } void object::activate () { /* If already on active list, don't do anything */ - if (active ()) + if (active) return; if (has_active_speed ()) - { - /* process_events() expects us to insert the object at the beginning - * of the list. */ - active_next = active_objects; - - if (active_next) - active_next->active_prev = this; - - active_objects = this; - } + actives.insert (this); } void @@ -735,7 +710,7 @@ { activate (); - for (object *op = inv; op; op = op->above) + for (object *op = inv; op; op = op->below) op->activate_recursive (); } @@ -751,35 +726,31 @@ object::deactivate () { /* If not on the active list, nothing needs to be done */ - if (!active ()) + if (!active) return; - if (active_prev == 0) - { - active_objects = active_next; - if (active_next) - active_next->active_prev = 0; - } - else - { - active_prev->active_next = active_next; - if (active_next) - active_next->active_prev = active_prev; - } - - active_next = 0; - active_prev = 0; + actives.erase (this); } void object::deactivate_recursive () { - for (object *op = inv; op; op = op->above) + for (object *op = inv; op; op = op->below) op->deactivate_recursive (); deactivate (); } +void +object::set_flag_inv (int flag, int value) +{ + for (object *op = inv; op; op = op->below) + { + op->flag [flag] = value; + op->set_flag_inv (flag, value); + } +} + /* * Remove and free all objects in the inventory of the given object. * object.c ? @@ -820,7 +791,8 @@ || op->flag [FLAG_NO_DROP] || op->type == RUNE || op->type == TRAP - || op->flag [FLAG_IS_A_TEMPLATE]) + || op->flag [FLAG_IS_A_TEMPLATE] + || op->flag [FLAG_DESTROY_ON_DEATH]) op->destroy (); else map->insert (op, x, y); @@ -838,6 +810,8 @@ void object::do_destroy () { + attachable::do_destroy (); + if (flag [FLAG_IS_LINKED]) remove_button_link (this); @@ -847,18 +821,13 @@ if (!flag [FLAG_REMOVED]) remove (); - if (flag [FLAG_FREED]) - return; + destroy_inv (true); - set_speed (0); + deactivate (); + unlink (); flag [FLAG_FREED] = 1; - attachable::do_destroy (); - - destroy_inv (true); - unlink (); - // hack to ensure that freed objects still have a valid map { static maptile *freed_map; // freed objects are moved here to avoid crashes @@ -872,6 +841,7 @@ freed_map->height = 3; freed_map->alloc (); + freed_map->in_memory = MAP_IN_MEMORY; } map = freed_map; @@ -891,9 +861,6 @@ owner = 0; enemy = 0; attacked_by = 0; - - // only relevant for players(?), but make sure of it anyways - contr = 0; } void @@ -988,7 +955,7 @@ if (type == PLAYER) { --map->players; - map->last_access = runtime; + map->touch (); } map->dirty = true; @@ -1205,10 +1172,10 @@ object *more = op->more; - /* We really need the caller to normalize coordinates - if + /* 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 normalize it. + * 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); @@ -1378,7 +1345,7 @@ { op->contr->do_los = 1; ++op->map->players; - op->map->last_access = runtime; + op->map->touch (); } op->map->dirty = true; @@ -1445,7 +1412,7 @@ /* first search for itself and remove any old instances */ - for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) + for (tmp = op->ms ().bot; tmp; tmp = tmp->above) if (!strcmp (tmp->arch->name, arch_string)) /* same archetype */ tmp->destroy (); @@ -1778,7 +1745,7 @@ * Hence, we first go to the top: */ - for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp && tmp->above; tmp = tmp->above) + for (tmp = op->ms ().bot; tmp && tmp->above; tmp = tmp->above) { /* Trim the search when we find the first other spell effect * this helps performance so that if a space has 50 spell objects, @@ -1846,13 +1813,13 @@ object * present_arch (const archetype *at, maptile *m, int x, int y) { - if (m == NULL || out_of_map (m, x, y)) + if (!m || out_of_map (m, x, y)) { LOG (llevError, "Present_arch called outside map.\n"); return NULL; } - for (object *tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) + for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above) if (tmp->arch == at) return tmp; @@ -1873,7 +1840,7 @@ return NULL; } - for (object *tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = tmp->above) + for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above) if (tmp->type == type) return tmp; @@ -2198,28 +2165,9 @@ } /* - * absdir(int): Returns a number between 1 and 8, which represent - * the "absolute" direction of a number (it actually takes care of - * "overflow" in previous calculations of a direction). - */ - -int -absdir (int d) -{ - while (d < 1) - d += 8; - - while (d > 8) - d -= 8; - - return d; -} - -/* * dirdiff(dir1, dir2) returns how many 45-degrees differences there is * between two directions (which are expected to be absolute (see absdir()) */ - int dirdiff (int dir1, int dir2) { @@ -2615,6 +2563,8 @@ char *p = desc; bool first = true; + *p = 0; + for (int i = 0; i < NUM_FLAGS; i++) { if (len <= 10) // magic constant! @@ -2623,7 +2573,7 @@ break; } - if (flag[i]) + if (flag [i]) { int cnt = snprintf (p, len, "%s%d", first ? "" : ",", i); len -= cnt; @@ -2635,7 +2585,7 @@ return desc; } -// return a suitable string describing an objetc in enough detail to find it +// return a suitable string describing an object in enough detail to find it const char * object::debug_desc (char *info) const { @@ -2662,7 +2612,14 @@ const char * object::debug_desc () const { - static char info[256 * 3]; + static char info[256 * 4]; + return debug_desc (info); +} + +const char * +object::debug_desc2 () const +{ + static char info[256 * 4]; return debug_desc (info); }