--- deliantra/server/common/map.C 2006/12/30 10:16:10 1.56 +++ deliantra/server/common/map.C 2007/01/01 21:19:51 1.65 @@ -38,78 +38,9 @@ const char * create_pathname (const char *name) { - static char buf[MAX_BUF]; - - /* Why? having extra / doesn't confuse unix anyplace? Dependancies - * someplace else in the code? msw 2-17-97 - */ - if (*name == '/') - sprintf (buf, "%s/%s%s", settings.datadir, settings.mapdir, name); - else - sprintf (buf, "%s/%s/%s", settings.datadir, settings.mapdir, name); - return (buf); -} - -/* - * same as create_pathname, but for the overlay maps. - */ -const char * -create_overlay_pathname (const char *name) -{ - static char buf[MAX_BUF]; - - /* Why? having extra / doesn't confuse unix anyplace? Dependancies - * someplace else in the code? msw 2-17-97 - */ - if (*name == '/') - sprintf (buf, "%s/%s%s", settings.localdir, settings.mapdir, name); - else - sprintf (buf, "%s/%s/%s", settings.localdir, settings.mapdir, name); - return (buf); -} - -/* - * same as create_pathname, but for the template maps. - */ -const char * -create_template_pathname (const char *name) -{ - static char buf[MAX_BUF]; - - /* Why? having extra / doesn't confuse unix anyplace? Dependancies - * someplace else in the code? msw 2-17-97 - */ - if (*name == '/') - sprintf (buf, "%s/%s%s", settings.localdir, settings.templatedir, name); - else - sprintf (buf, "%s/%s/%s", settings.localdir, settings.templatedir, name); - return (buf); -} - -/* - * This makes absolute path to the itemfile where unique objects - * will be saved. Converts '/' to '@'. I think it's essier maintain - * files than full directory structure, but if this is problem it can - * be changed. - */ -static const char * -create_items_path (const char *s) -{ - static char buf[MAX_BUF]; - char *t; - - if (*s == '/') - s++; - - sprintf (buf, "%s/%s/", settings.localdir, settings.uniquedir); - - for (t = buf + strlen (buf); *s; s++, t++) - if (*s == '/') - *t = '@'; - else - *t = *s; - *t = 0; - return (buf); + static char buf[8192]; + snprintf (buf, sizeof (buf), "%s/%s/%s", settings.datadir, settings.mapdir, name); + return buf; } /* @@ -333,7 +264,7 @@ maptile *m1; sint16 sx, sy; - if (ob == NULL) + if (!ob) { flag = get_map_flags (m, &m1, x, y, &sx, &sy); if (flag & P_OUT_OF_MAP) @@ -400,6 +331,17 @@ sum_weight (container); } +void +maptile::set_object_flag (int flag, int value) +{ + if (!spaces) + return; + + for (mapspace *ms = spaces + size (); ms-- > spaces; ) + for (object *tmp = ms->bot; tmp; tmp = tmp->above) + tmp->flag [flag] = value; +} + /* link_multipart_objects go through all the objects on the map looking * for objects whose arch says they are multipart yet according to the * info we have, they only have the head (as would be expected when @@ -530,7 +472,7 @@ for (mapspace *ms = spaces + size (); ms-- > spaces; ) for (object *op = ms->bot; op; op = op->above) - op->activate (1); + op->activate_recursive (); } void @@ -541,12 +483,14 @@ for (mapspace *ms = spaces + size (); ms-- > spaces; ) for (object *op = ms->bot; op; op = op->above) - op->deactivate (1); + op->deactivate_recursive (); } bool maptile::save_objects (object_freezer &freezer, int flags) { + static int cede_count = 0; + if (flags & IO_HEADER) save_header (freezer); @@ -555,9 +499,18 @@ for (int i = 0; i < size (); ++i) { + if (cede_count >= 500) + { + cede_count = 0; + coroapi::cede (); + } + int unique = 0; for (object *op = spaces [i].bot; op; op = op->above) { + // count per-object, but cede only when modification-safe + cede_count++; + if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR]) unique = 1; @@ -791,7 +744,7 @@ switch (kw) { case KW_EOF: - LOG (llevError, "%s: end of file while reading map header, aborting header load.", &path); + LOG (llevError, "%s: end of file while reading map header, aborting header load.\n", &path); return false; case KW_end: @@ -959,7 +912,8 @@ if (tile_path [2]) MAP_OUT2 (tile_path_3, tile_path [2]); if (tile_path [3]) MAP_OUT2 (tile_path_4, tile_path [3]); - MAP_OUT2 (end, 0); + freezer.put (this); + freezer.put (KW_end); return true; } @@ -1326,19 +1280,6 @@ faces [2] = floor; faces_obj [2] = floor != blank_face ? floor_obj : 0; } -void -set_map_reset_time (maptile *map) -{ - int timeout = map->reset_timeout; - - if (timeout <= 0) - timeout = MAP_DEFAULTRESET; - if (timeout >= MAP_MAXRESET) - timeout = MAP_MAXRESET; - - map->reset_time = time (0) + timeout; -} - /* this updates the orig_map->tile_map[tile_num] value after loading * the map. It also takes care of linking back the freshly loaded * maps tile_map values if it tiles back to this one. It returns @@ -1348,15 +1289,25 @@ static maptile * load_and_link_tiled_map (maptile *orig_map, int tile_num) { - maptile *mp = orig_map->find_map (orig_map->tile_path[tile_num]); - mp->load (); + maptile *mp = orig_map->load_map_sync (orig_map->tile_path [tile_num], orig_map); + + if (!mp || mp->in_memory != MAP_IN_MEMORY) + { + // 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; - /* need to do a strcmp here as the orig_map->path is not a shared string */ - if (orig_map->tile_map[tile_num]->tile_path[dest_tile] && orig_map->tile_map[tile_num]->tile_path[dest_tile] == orig_map->path) + // 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; return mp; @@ -1492,8 +1443,6 @@ /* Simple case - coordinates are within this local * map. */ - - m->last_access = runtime; return m; }