--- deliantra/server/common/map.C 2006/08/28 16:12:59 1.11 +++ deliantra/server/common/map.C 2006/09/08 12:56:42 1.27 @@ -1,6 +1,6 @@ /* * static char *rcsid_map_c = - * "$Id: map.C,v 1.11 2006/08/28 16:12:59 root Exp $"; + * "$Id: map.C,v 1.27 2006/09/08 12:56:42 root Exp $"; */ /* @@ -157,7 +157,7 @@ #ifndef WIN32 char *endbuf; struct stat statbuf; - int mode = 0, i; + int mode = 0; #endif if (prepend_dir) @@ -175,16 +175,8 @@ */ endbuf = buf + strlen(buf); - for (i = 0; i < NROF_COMPRESS_METHODS; i++) { - if (uncomp[i][0]) - strcpy(endbuf, uncomp[i][0]); - else - *endbuf = '\0'; - if (!stat (buf, &statbuf)) - break; - } - if (i == NROF_COMPRESS_METHODS) - return (-1); + if (stat (buf, &statbuf)) + return -1; if (!S_ISREG (statbuf.st_mode)) return (-1); @@ -492,14 +484,8 @@ op->head = tmp; op->map = m; last->more = op; - if (tmp->name != op->name) { - if (op->name) free_string(op->name); - op->name = add_string(tmp->name); - } - if (tmp->title != op->title) { - if (op->title) free_string(op->title); - op->title = add_string(tmp->title); - } + op->name = tmp->name; + op->title = tmp->title; /* we could link all the parts onto tmp, and then just * call insert_ob_in_map once, but the effect is the same, * as insert_ob_in_map will call itself with each part, and @@ -510,79 +496,89 @@ } /* for objects on this space */ } - - /* * Loads (ands parses) the objects into a given map from the specified * file pointer. * mapflags is the same as we get with load_original_map */ +void +load_objects (mapstruct *m, object_thawer &fp, int mapflags) +{ + int i, j; + int unique; + object *op, *prev = NULL, *last_more = NULL, *otmp; -void load_objects (mapstruct *m, object_thawer &fp, int mapflags) { - int i,j,bufstate=LO_NEWFILE; - int unique; - object *op, *prev=NULL,*last_more=NULL, *otmp; - - op=get_object(); - op->map = m; /* To handle buttons correctly */ - - while((i = load_object (fp, op, bufstate, mapflags))) { - /* Since the loading of the map header does not load an object - * anymore, we need to pass LO_NEWFILE for the first object loaded, - * and then switch to LO_REPEAT for faster loading. - */ - bufstate = LO_REPEAT; + op = get_object (); + op->map = m; /* To handle buttons correctly */ - /* if the archetype for the object is null, means that we - * got an invalid object. Don't do anything with it - the game - * or editor will not be able to do anything with it either. - */ - if (op->arch==NULL) { - LOG(llevDebug,"Discarding object without arch: %s\n", op->name?op->name:"(null)"); - continue; + while ((i = load_object (fp, op, mapflags))) + { + /* if the archetype for the object is null, means that we + * got an invalid object. Don't do anything with it - the game + * or editor will not be able to do anything with it either. + */ + if (op->arch == NULL) + { + LOG (llevDebug, "Discarding object without arch: %s\n", + op->name ? (const char *) op->name : "(null)"); + continue; } - switch(i) { + switch (i) + { case LL_NORMAL: /* if we are loading an overlay, put the floors on the bottom */ - if ((QUERY_FLAG(op, FLAG_IS_FLOOR) || - QUERY_FLAG(op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) - insert_ob_in_map(op,m,op,INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY | INS_MAP_LOAD); + if ((QUERY_FLAG (op, FLAG_IS_FLOOR) || + QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) + insert_ob_in_map (op, m, op, + INS_NO_MERGE | INS_NO_WALK_ON | + INS_ABOVE_FLOOR_ONLY | INS_MAP_LOAD); else - insert_ob_in_map(op,m,op,INS_NO_MERGE | INS_NO_WALK_ON | INS_ON_TOP | INS_MAP_LOAD); + insert_ob_in_map (op, m, op, + INS_NO_MERGE | INS_NO_WALK_ON | INS_ON_TOP | + INS_MAP_LOAD); if (op->inv) - sum_weight(op); + sum_weight (op); - prev=op,last_more=op; + prev = op, last_more = op; break; case LL_MORE: - insert_ob_in_map(op,m, op, INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); - op->head=prev,last_more->more=op,last_more=op; + insert_ob_in_map (op, m, op, + INS_NO_MERGE | INS_NO_WALK_ON | + INS_ABOVE_FLOOR_ONLY); + op->head = prev, last_more->more = op, last_more = op; break; } - if (mapflags & MAP_STYLE) { - remove_from_active_list(op); - } - op=get_object(); - op->map = m; + + if (mapflags & MAP_STYLE) + remove_from_active_list (op); + + op = get_object (); + op->map = m; } - for (i=0;iwidth;i++){ - for (j=0;jheight;j++){ - unique =0; - /* check for unique items, or unique squares */ - for (otmp = get_map_ob(m, i, j); otmp; otmp = otmp->above) { - if (QUERY_FLAG(otmp, FLAG_UNIQUE) || QUERY_FLAG(otmp, FLAG_OBJ_SAVE_ON_OVL)) - unique = 1; - if (!(mapflags & (MAP_OVERLAY|MAP_PLAYER_UNIQUE) || unique)) - SET_FLAG(otmp, FLAG_OBJ_ORIGINAL); + + for (i = 0; i < m->width; i++) + { + for (j = 0; j < m->height; j++) + { + unique = 0; + /* check for unique items, or unique squares */ + for (otmp = get_map_ob (m, i, j); otmp; otmp = otmp->above) + { + if (QUERY_FLAG (otmp, FLAG_UNIQUE) + || QUERY_FLAG (otmp, FLAG_OBJ_SAVE_ON_OVL)) + unique = 1; + if (!(mapflags & (MAP_OVERLAY | MAP_PLAYER_UNIQUE) || unique)) + SET_FLAG (otmp, FLAG_OBJ_ORIGINAL); } } } - free_object(op); - link_multipart_objects(m); + + free_object (op); + link_multipart_objects (m); } /* This saves all the objects on the map in a non destructive fashion. @@ -628,12 +624,9 @@ */ mapstruct *get_linked_map(void) { - mapstruct *map=(mapstruct *) calloc(1,sizeof(mapstruct)); + mapstruct *map = new mapstruct; mapstruct *mp; - if(map==NULL) - fatal(OUT_OF_MEMORY); - for(mp=first_map;mp!=NULL&&mp->next!=NULL;mp=mp->next); if(mp==NULL) first_map=map; @@ -713,8 +706,7 @@ } p=shop_string; strip_endline(p); - items=(shopitems *) CALLOC(number_of_entries+1, sizeof(shopitems)); - memset(items, 0, (sizeof(shopitems) * number_of_entries+1)); + items = new shopitems [number_of_entries + 1]; for (i=0; iattach = value; } else if (!strcmp(key,"hp") || !strcmp(key, "enter_x")) { m->enter_x = atoi(value); } else if (!strcmp(key,"sp") || !strcmp(key, "enter_y")) { @@ -949,8 +943,6 @@ m->sky = atoi(value); } else if (!strcmp(key, "nosmooth")) { m->nosmooth = atoi(value); - } else if (!strcmp(key, "safe_map")) { - m->safe_map = atoi(value); } else if (!strncmp(key,"tile_path_", 10)) { int tile=atoi(key+10); @@ -1017,12 +1009,9 @@ */ mapstruct *load_original_map(const char *filename, int flags) { - FILE *fp; mapstruct *m; - int comp; char pathname[MAX_BUF]; - LOG(llevDebug, "load_original_map: %s (%x)\n", filename,flags); if (flags & MAP_PLAYER_UNIQUE) strcpy(pathname, filename); else if (flags & MAP_OVERLAY) @@ -1030,12 +1019,12 @@ else strcpy(pathname, create_pathname(filename)); - if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { - LOG(llevError, "Can't open %s: %s\n", pathname, strerror_local(errno)); - return (NULL); - } + LOG(llevDebug, "load_original_map(%x): %s (%s)\n", flags, filename, pathname); - object_thawer thawer (fp, filename); + object_thawer thawer (pathname); + + if (!thawer) + return 0; m = get_linked_map(); @@ -1051,12 +1040,12 @@ m->in_memory=MAP_LOADING; load_objects (m, thawer, flags & (MAP_BLOCK|MAP_STYLE)); - close_and_delete(fp, comp); + m->in_memory=MAP_IN_MEMORY; if (!MAP_DIFFICULTY(m)) MAP_DIFFICULTY(m)=calculate_difficulty(m); set_map_reset_time(m); - INVOKE_MAP (INSTANTIATE, m); + m->instantiate (); return (m); } @@ -1067,8 +1056,6 @@ */ static mapstruct *load_temporary_map(mapstruct *m) { - FILE *fp; - int comp; char buf[MAX_BUF]; if (!m->tmpname) { @@ -1081,17 +1068,17 @@ return m; } - if((fp=open_and_uncompress(m->tmpname,0, &comp))==NULL) { - LOG(llevError, "Cannot open %s: %s\n",m->tmpname, strerror_local(errno)); - strcpy(buf, m->path); - delete_map(m); - m = load_original_map(buf, 0); - if(m==NULL) return NULL; - fix_auto_apply(m); /* Chests which open as default */ - return m; - } + object_thawer thawer (m->tmpname); - object_thawer thawer (fp, m->tmpname); + if (!thawer) + { + strcpy (buf, m->path); + delete_map (m); + m = load_original_map (buf, 0); + if (!m) return NULL; + fix_auto_apply (m); /* Chests which open as default */ + return m; + } if (load_map_header(thawer, m)) { LOG(llevError,"Error loading map header for %s (%s)\n", @@ -1104,7 +1091,7 @@ m->in_memory=MAP_LOADING; load_objects (m, thawer, 0); - close_and_delete(fp, comp); + m->in_memory=MAP_IN_MEMORY; INVOKE_MAP (SWAPIN, m); return m; @@ -1117,18 +1104,14 @@ */ mapstruct *load_overlay_map(const char *filename, mapstruct *m) { - FILE *fp; - int comp; char pathname[MAX_BUF]; strcpy(pathname, create_overlay_pathname(filename)); - if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { -/* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ - return m; - } + object_thawer thawer (pathname); - object_thawer thawer (fp, pathname); + if (!thawer) + return m; if (load_map_header(thawer, m)) { LOG(llevError,"Error loading map header for overlay %s (%s)\n", @@ -1141,7 +1124,7 @@ m->in_memory=MAP_LOADING; load_objects (m, thawer, MAP_OVERLAY); - close_and_delete(fp, comp); + m->in_memory=MAP_IN_MEMORY; return m; } @@ -1180,8 +1163,7 @@ * m is the map to load unique items into. */ static void load_unique_objects(mapstruct *m) { - FILE *fp; - int comp,count; + int count; char firstname[MAX_BUF]; for (count=0; count<10; count++) { @@ -1191,22 +1173,16 @@ /* If we get here, we did not find any map */ if (count==10) return; - if ((fp=open_and_uncompress(firstname, 0, &comp))==NULL) { - /* There is no expectation that every map will have unique items, but this - * is debug output, so leave it in. - */ - LOG(llevDebug, "Can't open unique items file for %s\n", create_items_path(m->path)); - return; - } + object_thawer thawer (firstname); - object_thawer thawer (fp, firstname); + if (!thawer) + return; m->in_memory=MAP_LOADING; if (m->tmpname == NULL) /* if we have loaded unique items from */ delete_unique_items(m); /* original map before, don't duplicate them */ - load_object(thawer, NULL, LO_NOREAD,0); load_objects (m, thawer, 0); - close_and_delete(fp, comp); + m->in_memory=MAP_IN_MEMORY; } @@ -1223,7 +1199,7 @@ int new_save_map (mapstruct * m, int flag) { - char filename[MAX_BUF], buf[MAX_BUF], buf_s[MAX_BUF], shop[MAX_BUF]; + char filename[MAX_BUF], buf[MAX_BUF], shop[MAX_BUF]; int i; if (flag && !*m->path) @@ -1250,95 +1226,95 @@ { if (!m->tmpname) m->tmpname = tempnam_local (settings.tmpdir, NULL); + strcpy (filename, m->tmpname); } LOG (llevDebug, "Saving map %s to %s\n", m->path, filename); m->in_memory = MAP_SAVING; - object_freezer fp (filename); + object_freezer freezer; /* legacy */ - fprintf (fp, "arch map\n"); + fprintf (freezer, "arch map\n"); if (m->name) - fprintf (fp, "name %s\n", m->name); + fprintf (freezer, "name %s\n", m->name); if (!flag) - fprintf (fp, "swap_time %d\n", m->swap_time); + fprintf (freezer, "swap_time %d\n", m->swap_time); if (m->reset_timeout) - fprintf (fp, "reset_timeout %d\n", m->reset_timeout); + fprintf (freezer, "reset_timeout %d\n", m->reset_timeout); if (m->fixed_resettime) - fprintf (fp, "fixed_resettime %d\n", m->fixed_resettime); + fprintf (freezer, "fixed_resettime %d\n", m->fixed_resettime); /* we unfortunately have no idea if this is a value the creator set * or a difficulty value we generated when the map was first loaded */ if (m->difficulty) - fprintf (fp, "difficulty %d\n", m->difficulty); + fprintf (freezer, "difficulty %d\n", m->difficulty); if (m->region) - fprintf (fp, "region %s\n", m->region->name); + fprintf (freezer, "region %s\n", m->region->name); if (m->shopitems) { print_shop_string (m, shop); - fprintf (fp, "shopitems %s\n", shop); + fprintf (freezer, "shopitems %s\n", shop); } if (m->shopgreed) - fprintf (fp, "shopgreed %f\n", m->shopgreed); + fprintf (freezer, "shopgreed %f\n", m->shopgreed); #ifndef WIN32 if (m->shopmin) - fprintf (fp, "shopmin %llu\n", m->shopmin); + fprintf (freezer, "shopmin %llu\n", m->shopmin); if (m->shopmax) - fprintf (fp, "shopmax %llu\n", m->shopmax); + fprintf (freezer, "shopmax %llu\n", m->shopmax); #else if (m->shopmin) - fprintf (fp, "shopmin %I64u\n", m->shopmin); + fprintf (freezer, "shopmin %I64u\n", m->shopmin); if (m->shopmax) - fprintf (fp, "shopmax %I64u\n", m->shopmax); + fprintf (freezer, "shopmax %I64u\n", m->shopmax); #endif if (m->shoprace) - fprintf (fp, "shoprace %s\n", m->shoprace); + fprintf (freezer, "shoprace %s\n", m->shoprace); if (m->darkness) - fprintf (fp, "darkness %d\n", m->darkness); + fprintf (freezer, "darkness %d\n", m->darkness); if (m->width) - fprintf (fp, "width %d\n", m->width); + fprintf (freezer, "width %d\n", m->width); if (m->height) - fprintf (fp, "height %d\n", m->height); + fprintf (freezer, "height %d\n", m->height); if (m->enter_x) - fprintf (fp, "enter_x %d\n", m->enter_x); + fprintf (freezer, "enter_x %d\n", m->enter_x); if (m->enter_y) - fprintf (fp, "enter_y %d\n", m->enter_y); + fprintf (freezer, "enter_y %d\n", m->enter_y); if (m->msg) - fprintf (fp, "msg\n%sendmsg\n", m->msg); + fprintf (freezer, "msg\n%sendmsg\n", m->msg); if (m->maplore) - fprintf (fp, "maplore\n%sendmaplore\n", m->maplore); + fprintf (freezer, "maplore\n%sendmaplore\n", m->maplore); if (m->unique) - fprintf (fp, "unique %d\n", m->unique); + fprintf (freezer, "unique %d\n", m->unique); if (m->templatemap) - fprintf (fp, "template %d\n", m->templatemap); + fprintf (freezer, "template %d\n", m->templatemap); if (m->outdoor) - fprintf (fp, "outdoor %d\n", m->outdoor); + fprintf (freezer, "outdoor %d\n", m->outdoor); if (m->temp) - fprintf (fp, "temp %d\n", m->temp); + fprintf (freezer, "temp %d\n", m->temp); if (m->pressure) - fprintf (fp, "pressure %d\n", m->pressure); + fprintf (freezer, "pressure %d\n", m->pressure); if (m->humid) - fprintf (fp, "humid %d\n", m->humid); + fprintf (freezer, "humid %d\n", m->humid); if (m->windspeed) - fprintf (fp, "windspeed %d\n", m->windspeed); + fprintf (freezer, "windspeed %d\n", m->windspeed); if (m->winddir) - fprintf (fp, "winddir %d\n", m->winddir); + fprintf (freezer, "winddir %d\n", m->winddir); if (m->sky) - fprintf (fp, "sky %d\n", m->sky); + fprintf (freezer, "sky %d\n", m->sky); if (m->nosmooth) - fprintf (fp, "nosmooth %d\n", m->nosmooth); - if (m->safe_map) - fprintf (fp, "safe_map %d\n", m->safe_map); + fprintf (freezer, "nosmooth %d\n", m->nosmooth); /* Save any tiling information, except on overlays */ if (flag != 2) for (i = 0; i < 4; i++) if (m->tile_path[i]) - fprintf (fp, "tile_path_%d %s\n", i + 1, m->tile_path[i]); + fprintf (freezer, "tile_path_%d %s\n", i + 1, m->tile_path[i]); - fprintf (fp, "end\n"); + freezer.put (m); + fprintf (freezer, "end\n"); /* In the game save unique items in the different file, but * in the editor save them to the normal map file. @@ -1347,20 +1323,24 @@ */ if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) { - sprintf (buf, "%s.v00", create_items_path (m->path)); - - object_freezer fp2 (buf); + object_freezer unique; if (flag == 2) - save_objects (m, fp, fp2, 2); + save_objects (m, freezer, unique, 2); else - save_objects (m, fp, fp2, 0); + save_objects (m, freezer, unique, 0); + + sprintf (buf, "%s.v00", create_items_path (m->path)); + + unique.save (buf); } else { /* save same file when not playing, like in editor */ - save_objects (m, fp, fp, 0); + save_objects (m, freezer, freezer, 0); } + freezer.save (filename); + return 0; } @@ -1414,18 +1394,6 @@ free_object(op); } } -#ifdef MANY_CORES - /* I see periodic cores on metalforge where a map has been swapped out, but apparantly - * an item on that map was not saved - look for that condition and die as appropriate - - * this leaves more of the map data intact for better debugging. - */ - for (op=objects; op!=NULL; op=op->next) { - if (!QUERY_FLAG(op, FLAG_REMOVED) && op->map == m) { - LOG(llevDebug,"free_all_objects: object %s still on map after it should have been freed\n", op->name); - abort(); - } - } -#endif } /* @@ -1445,7 +1413,7 @@ if (m->spaces) FREE_AND_CLEAR(m->spaces); if (m->msg) FREE_AND_CLEAR(m->msg); if (m->maplore) FREE_AND_CLEAR(m->maplore); - if (m->shopitems) FREE_AND_CLEAR(m->shopitems); + if (m->shopitems) delete [] m->shopitems; m->shopitems = 0; if (m->shoprace) FREE_AND_CLEAR(m->shoprace); if (m->buttons) free_objectlinkpt(m->buttons); @@ -1515,7 +1483,7 @@ else last->next = m->next; - free (m); + delete m; } @@ -1568,15 +1536,17 @@ else LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); + //eval_pv ("$x = Event::time", 1);//D if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) return (NULL); + //eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D fix_auto_apply(m); /* Chests which open as default */ /* If a player unique map, no extra unique object file to load. * if from the editor, likewise. */ - if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) + if (!(flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) load_unique_objects(m); if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { @@ -1585,6 +1555,9 @@ return NULL; } + if (flags & MAP_PLAYER_UNIQUE) + INVOKE_MAP (SWAPIN, m); + } else { /* If in this loop, we found a temporary map, so load it up. */ @@ -1634,7 +1607,7 @@ int calculate_difficulty(mapstruct *m) { object *op; archetype *at; - int x, y, i, diff; + int x, y, i; long monster_cnt = 0; double avgexp = 0; sint64 total_exp = 0;