--- deliantra/server/common/map.C 2006/08/15 17:35:50 1.3 +++ deliantra/server/common/map.C 2006/08/27 16:15:11 1.9 @@ -1,6 +1,6 @@ /* * static char *rcsid_map_c = - * "$Id: map.C,v 1.3 2006/08/15 17:35:50 elmex Exp $"; + * "$Id: map.C,v 1.9 2006/08/27 16:15:11 root Exp $"; */ /* @@ -40,10 +40,6 @@ extern int nrofallocobjects,nroffreeobjects; -void (*load_original_map_callback)(mapstruct *map); -void (*load_temporary_map_callback)(mapstruct *map); -void (*clean_temporary_map_callback)(mapstruct *map); - /* * Returns the mapstruct which has a name matching the given argument. * return NULL if no match is found. @@ -522,7 +518,7 @@ * mapflags is the same as we get with load_original_map */ -void load_objects (mapstruct *m, FILE *fp, int mapflags) { +void load_objects (mapstruct *m, FILE *fp, object_thawer &thawer, int mapflags) { int i,j,bufstate=LO_NEWFILE; int unique; object *op, *prev=NULL,*last_more=NULL, *otmp; @@ -530,7 +526,7 @@ op=get_object(); op->map = m; /* To handle buttons correctly */ - while((i=load_object(fp,op,bufstate, mapflags))) { + while((i = load_object (fp, thawer, 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. @@ -594,7 +590,7 @@ * and we only save the head of multi part objects - this is needed * in order to do map tiling properly. */ -void save_objects (mapstruct *m, FILE *fp, FILE *fp2, int flag) { +void save_objects (mapstruct *m, FILE *fp, object_freezer &freezer, FILE *fp2, object_freezer &freezer2, int flag) { int i, j = 0,unique=0; object *op; /* first pass - save one-part objects */ @@ -614,12 +610,12 @@ continue; if (unique || QUERY_FLAG(op, FLAG_UNIQUE)) - save_object( fp2 , op, 3); + save_object( fp2 , freezer2, op, 3); else if (flag == 0 || (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) && !QUERY_FLAG(op, FLAG_UNPAID)))) - save_object(fp, op, 3); + save_object(fp, freezer, op, 3); } /* for this space */ } /* for this j */ @@ -1037,6 +1033,8 @@ return (NULL); } + object_thawer thawer (filename); + m = get_linked_map(); strcpy (m->path, filename); @@ -1051,14 +1049,13 @@ m->compressed = comp; m->in_memory=MAP_LOADING; - load_objects (m, fp, flags & (MAP_BLOCK|MAP_STYLE)); + load_objects (m, fp, 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); - if (load_original_map_callback) - load_original_map_callback(m); + INVOKE_MAP (LOAD, m); return (m); } @@ -1092,7 +1089,8 @@ fix_auto_apply(m); /* Chests which open as default */ return m; } - + + object_thawer thawer (m->tmpname); if (load_map_header(fp, m)) { LOG(llevError,"Error loading map header for %s (%s)\n", @@ -1105,11 +1103,10 @@ allocate_map(m); m->in_memory=MAP_LOADING; - load_objects (m, fp, 0); + load_objects (m, fp, thawer, 0); close_and_delete(fp, comp); m->in_memory=MAP_IN_MEMORY; - if (load_temporary_map_callback) - load_temporary_map_callback(m); + INVOKE_MAP (SWAPIN, m); return m; } @@ -1130,6 +1127,8 @@ /* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ return m; } + + object_thawer thawer (pathname); if (load_map_header(fp, m)) { LOG(llevError,"Error loading map header for overlay %s (%s)\n", @@ -1142,7 +1141,7 @@ /*allocate_map(m);*/ m->in_memory=MAP_LOADING; - load_objects (m, fp, MAP_OVERLAY); + load_objects (m, fp, thawer, MAP_OVERLAY); close_and_delete(fp, comp); m->in_memory=MAP_IN_MEMORY; return m; @@ -1201,11 +1200,13 @@ return; } + object_thawer thawer (firstname); + 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(fp, NULL, LO_NOREAD,0); - load_objects (m, fp, 0); + load_object(fp, thawer, NULL, LO_NOREAD,0); + load_objects (m, fp, thawer, 0); close_and_delete(fp, comp); m->in_memory=MAP_IN_MEMORY; } @@ -1222,7 +1223,8 @@ int new_save_map(mapstruct *m, int flag) { FILE *fp, *fp2; - char filename[MAX_BUF],buf[MAX_BUF], shop[MAX_BUF]; + char filename[MAX_BUF],buf[MAX_BUF], buf_s[MAX_BUF], + shop[MAX_BUF], filename_s[MAX_BUF]; int i; if (flag && !*m->path) { @@ -1253,25 +1255,27 @@ m->tmpname = tempnam_local(settings.tmpdir,NULL); strcpy(filename, m->tmpname); } - LOG(llevDebug,"Saving map %s\n",m->path); + LOG(llevDebug,"Saving map %s to %s\n", m->path, filename); m->in_memory = MAP_SAVING; - unlink (filename); // do not overwrite backups if done via hardlinks + sprintf (filename_s, "%s~", filename); /* Compress if it isn't a temporary save. Do compress if unique */ if (m->compressed && (m->unique || m->templatemap || flag)) { char buf[MAX_BUF]; strcpy(buf, uncomp[m->compressed][2]); strcat(buf, " > "); - strcat(buf, filename); + strcat(buf, filename_s); fp = popen(buf, "w"); } else - fp = fopen(filename, "w"); + fp = fopen(filename_s, "w"); if(fp == NULL) { - LOG(llevError, "Cannot write %s: %s\n", filename, strerror_local(errno)); + LOG(llevError, "Cannot write %s: %s\n", filename_s, strerror_local(errno)); return -1; } + + object_freezer freezer (filename); /* legacy */ fprintf(fp,"arch map\n"); @@ -1329,27 +1333,32 @@ * If unique map, save files in the proper destination (set by * player) */ - fp2 = fp; /* save unique items into fp2 */ if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) { sprintf (buf,"%s.v00",create_items_path (m->path)); - if ((fp2 = fopen (buf, "w")) == NULL) { - LOG(llevError, "Can't open unique items file %s\n", buf); + sprintf (buf_s, "%s~", buf); + if ((fp2 = fopen (buf_s, "w")) == NULL) { + LOG(llevError, "Can't open unique items file %s\n", buf_s); } + + object_freezer freezer2 (buf); + if (flag == 2) - save_objects(m, fp, fp2, 2); + save_objects(m, fp, freezer, fp2, freezer2, 2); else - save_objects (m, fp, fp2, 0); + save_objects (m, fp,freezer, fp2, freezer2, 0); if (fp2 != NULL) { if (ftell (fp2) == 0) { fclose (fp2); + rename (buf_s, buf); unlink (buf); } else { fclose (fp2); + rename (buf_s, buf); chmod (buf, SAVE_MODE); } } } else { /* save same file when not playing, like in editor */ - save_objects(m, fp, fp, 0); + save_objects(m, fp, freezer, fp, freezer, 0); } if (m->compressed && (m->unique || m->templatemap || flag)) @@ -1357,6 +1366,8 @@ else fclose(fp); + rename (filename_s, filename); + chmod (filename, SAVE_MODE); return 0; } @@ -1678,8 +1689,7 @@ void clean_tmp_map(mapstruct *m) { if(m->tmpname == NULL) return; - if (clean_temporary_map_callback) - clean_temporary_map_callback (m); + INVOKE_MAP (CLEAN, m); (void) unlink(m->tmpname); } @@ -1828,8 +1838,8 @@ flags |= P_NO_MAGIC; if (QUERY_FLAG(tmp,FLAG_DAMNED)) flags |= P_NO_CLERIC; - if (tmp->type == SAFE_FLOOR) - flags |= P_SAFE; + if (tmp->type == SAFE_GROUND) + flags |= P_SAFE | P_NO_CLERIC | P_NO_MAGIC; if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW)) flags |= P_BLOCKSVIEW;