--- deliantra/server/common/map.C 2007/08/15 04:57:48 1.116 +++ deliantra/server/common/map.C 2007/09/07 18:03:31 1.127 @@ -385,21 +385,21 @@ for (int i = 0; i < size (); ++i) { - int unique = 0; + bool unique = 0; + for (object *op = spaces [i].bot; op; op = op->above) { - if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR]) - unique = 1; + unique |= op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR]; - if (!op->can_map_save ()) + if (expect_false (!op->can_map_save ())) continue; - if (unique || op->flag [FLAG_UNIQUE]) + if (expect_false (unique || op->flag [FLAG_UNIQUE])) { if (flags & IO_UNIQUES) op->write (f); } - else if (flags & IO_OBJECTS) + else if (expect_true (flags & IO_OBJECTS)) op->write (f); } } @@ -410,28 +410,6 @@ } bool -maptile::_load_objects (const char *path, bool skip_header) -{ - object_thawer f (path); - - if (!f) - return false; - - f.next (); - - if (skip_header) - for (;;) - { - keyword kw = f.kw; - f.skip (); - if (kw == KW_end) - break; - } - - return _load_objects (f); -} - -bool maptile::_save_objects (const char *path, int flags) { object_freezer freezer; @@ -613,8 +591,6 @@ { for (;;) { - thawer.next (); - switch (thawer.kw) { case KW_msg: @@ -679,10 +655,11 @@ case KW_tile_path_4: thawer.get (tile_path [3]); break; case KW_ERROR: - set_key (thawer.kw_str, thawer.value); + set_key_text (thawer.kw_str, thawer.value); break; case KW_end: + thawer.next (); return true; default: @@ -690,22 +667,13 @@ return false; break; } + + thawer.next (); } abort (); } -bool -maptile::_load_header (const char *path) -{ - object_thawer thawer (path); - - if (!thawer) - return false; - - return _load_header (thawer); -} - /****************************************************************************** * This is the start of unique map handling code *****************************************************************************/ @@ -812,17 +780,22 @@ void maptile::clear () { - sfree (regions, size ()); regions = 0; - delete [] regionmap; regionmap = 0; - if (spaces) { for (mapspace *ms = spaces + size (); ms-- > spaces; ) while (object *op = ms->bot) { - op = op->head_ (); - op->destroy_inv (false); - op->destroy (); + // manually remove, as to not trigger anything + if (ms->bot = op->above) + ms->bot->below = 0; + + op->flag [FLAG_REMOVED] = true; + + if (op == op->head_ ()) + { + op->destroy_inv (false); + op->destroy (); + } } sfree (spaces, size ()), spaces = 0; @@ -830,6 +803,9 @@ if (buttons) free_objectlinkpt (buttons), buttons = 0; + + sfree (regions, size ()); regions = 0; + delete [] regionmap; regionmap = 0; } void @@ -891,7 +867,6 @@ if (QUERY_FLAG (op, FLAG_IS_FLOOR) || QUERY_FLAG (op, FLAG_OBJ_ORIGINAL) - || QUERY_FLAG (op, FLAG_OBJ_SAVE_ON_OVL) || QUERY_FLAG (op, FLAG_UNIQUE) || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR) || QUERY_FLAG (op, FLAG_UNPAID) @@ -1226,47 +1201,19 @@ return vol; } -/* this updates the orig_map->tile_map[tile_num] value after finding - * the map. It also takes care of linking back the freshly found - * maps tile_map values if it tiles back to this one. It returns - * the value of orig_map->tile_map[tile_num]. - */ -static inline maptile * -find_and_link (maptile *orig_map, int tile_num) +bool +maptile::tile_available (int dir, bool load) { - maptile *mp = orig_map->tile_map [tile_num]; - - if (!mp) - { - mp = orig_map->find_sync (orig_map->tile_path [tile_num], orig_map); - - if (!mp) - { - // emergency mode, manufacture a dummy map, this creates a memleak, but thats fine - LOG (llevError, "FATAL: cannot load tiled map %s from %s, leaking memory and worse!\n", - &orig_map->tile_path[tile_num], &orig_map->path); - mp = new maptile (1, 1); - mp->alloc (); - mp->in_memory = MAP_IN_MEMORY; - } - } - - int dest_tile = (tile_num + 2) % 4; - - orig_map->tile_map [tile_num] = mp; + if (!tile_path[dir]) + return 0; - // optimisation: back-link map to origin map if euclidean - //TODO: non-euclidean maps MUST GO - if (orig_map->tile_map[tile_num]->tile_path[dest_tile] == orig_map->path) - orig_map->tile_map[tile_num]->tile_map[dest_tile] = orig_map; + if (tile_map[dir] && (!load || tile_map[dir]->in_memory == MAP_IN_MEMORY)) + return 1; - return mp; -} + if ((tile_map[dir] = find_async (tile_path[dir], this, load))) + return 1; -static inline void -load_and_link (maptile *orig_map, int tile_num) -{ - find_and_link (orig_map, tile_num)->load_sync (); + return 0; } /* this returns TRUE if the coordinates (x,y) are out of @@ -1289,45 +1236,33 @@ if (x < 0) { - if (!m->tile_path[3]) + if (!m->tile_available (3)) return 1; - if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) - find_and_link (m, 3); - return out_of_map (m->tile_map[3], x + m->tile_map[3]->width, y); } if (x >= m->width) { - if (!m->tile_path[1]) + if (!m->tile_available (1)) return 1; - if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) - find_and_link (m, 1); - return out_of_map (m->tile_map[1], x - m->width, y); } if (y < 0) { - if (!m->tile_path[0]) + if (!m->tile_available (0)) return 1; - if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) - find_and_link (m, 0); - return out_of_map (m->tile_map[0], x, y + m->tile_map[0]->height); } if (y >= m->height) { - if (!m->tile_path[2]) + if (!m->tile_available (2)) return 1; - if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) - find_and_link (m, 2); - return out_of_map (m->tile_map[2], x, y - m->height); } @@ -1350,40 +1285,36 @@ { if (x < 0) { - if (!tile_path[3]) + if (!tile_available (3)) return 0; - find_and_link (this, 3); x += tile_map[3]->width; return tile_map[3]->xy_find (x, y); } if (x >= width) { - if (!tile_path[1]) + if (!tile_available (1)) return 0; - find_and_link (this, 1); x -= width; return tile_map[1]->xy_find (x, y); } if (y < 0) { - if (!tile_path[0]) + if (!tile_available (0)) return 0; - find_and_link (this, 0); y += tile_map[0]->height; return tile_map[0]->xy_find (x, y); } if (y >= height) { - if (!tile_path[2]) + if (!tile_available (2)) return 0; - find_and_link (this, 2); y -= height; return tile_map[2]->xy_find (x, y); } @@ -1404,7 +1335,7 @@ if (!map1 || !map2) return 0; - //TODO: this doesn't actually check corretcly when intermediate maps are not loaded + //TODO: this doesn't actually check correctly when intermediate maps are not loaded //fix: compare paths instead (this is likely faster, too!) if (map1 == map2) { @@ -1675,11 +1606,11 @@ return; for_all_players (pl) - if (pl->ob->map == this) + if (pl->observe->map == this) if (client *ns = pl->ns) { - int dx = x - pl->ob->x; - int dy = y - pl->ob->y; + int dx = x - pl->observe->x; + int dy = y - pl->observe->y; int distance = idistance (dx, dy);