ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/map.C
(Generate patch)

Comparing deliantra/server/common/map.C (file contents):
Revision 1.2 by elmex, Tue Aug 15 15:00:20 2006 UTC vs.
Revision 1.9 by root, Sun Aug 27 16:15:11 2006 UTC

1/* 1/*
2 * static char *rcsid_map_c = 2 * static char *rcsid_map_c =
3 * "$Id: map.C,v 1.2 2006/08/15 15:00:20 elmex Exp $"; 3 * "$Id: map.C,v 1.9 2006/08/27 16:15:11 root Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
37 37
38#include "path.h" 38#include "path.h"
39 39
40 40
41extern int nrofallocobjects,nroffreeobjects; 41extern int nrofallocobjects,nroffreeobjects;
42
43void (*load_original_map_callback)(mapstruct *map);
44void (*load_temporary_map_callback)(mapstruct *map);
45void (*clean_temporary_map_callback)(mapstruct *map);
46 42
47/* 43/*
48 * Returns the mapstruct which has a name matching the given argument. 44 * Returns the mapstruct which has a name matching the given argument.
49 * return NULL if no match is found. 45 * return NULL if no match is found.
50 */ 46 */
268 retval |= P_NEW_MAP; 264 retval |= P_NEW_MAP;
269 if (newmap) *newmap = mp; 265 if (newmap) *newmap = mp;
270 if (nx) *nx = newx; 266 if (nx) *nx = newx;
271 if (ny) *ny = newy; 267 if (ny) *ny = newy;
272 retval |= mp->spaces[newx + mp->width * newy].flags; 268 retval |= mp->spaces[newx + mp->width * newy].flags;
273 if (mp->safe_map) 269
270 if (retval & P_SAFE)
274 retval |= P_NO_MAGIC | P_NO_CLERIC | P_SAFE_MAP; 271 retval |= P_NO_MAGIC | P_NO_CLERIC; // P_SAFE does imply these
272
275 return retval; 273 return retval;
276} 274}
277 275
278 276
279/* 277/*
518 * Loads (ands parses) the objects into a given map from the specified 516 * Loads (ands parses) the objects into a given map from the specified
519 * file pointer. 517 * file pointer.
520 * mapflags is the same as we get with load_original_map 518 * mapflags is the same as we get with load_original_map
521 */ 519 */
522 520
523void load_objects (mapstruct *m, FILE *fp, int mapflags) { 521void load_objects (mapstruct *m, FILE *fp, object_thawer &thawer, int mapflags) {
524 int i,j,bufstate=LO_NEWFILE; 522 int i,j,bufstate=LO_NEWFILE;
525 int unique; 523 int unique;
526 object *op, *prev=NULL,*last_more=NULL, *otmp; 524 object *op, *prev=NULL,*last_more=NULL, *otmp;
527 525
528 op=get_object(); 526 op=get_object();
529 op->map = m; /* To handle buttons correctly */ 527 op->map = m; /* To handle buttons correctly */
530 528
531 while((i=load_object(fp,op,bufstate, mapflags))) { 529 while((i = load_object (fp, thawer, op, bufstate, mapflags))) {
532 /* Since the loading of the map header does not load an object 530 /* Since the loading of the map header does not load an object
533 * anymore, we need to pass LO_NEWFILE for the first object loaded, 531 * anymore, we need to pass LO_NEWFILE for the first object loaded,
534 * and then switch to LO_REPEAT for faster loading. 532 * and then switch to LO_REPEAT for faster loading.
535 */ 533 */
536 bufstate = LO_REPEAT; 534 bufstate = LO_REPEAT;
590/* This saves all the objects on the map in a non destructive fashion. 588/* This saves all the objects on the map in a non destructive fashion.
591 * Modified by MSW 2001-07-01 to do in a single pass - reduces code, 589 * Modified by MSW 2001-07-01 to do in a single pass - reduces code,
592 * and we only save the head of multi part objects - this is needed 590 * and we only save the head of multi part objects - this is needed
593 * in order to do map tiling properly. 591 * in order to do map tiling properly.
594 */ 592 */
595void save_objects (mapstruct *m, FILE *fp, FILE *fp2, int flag) { 593void save_objects (mapstruct *m, FILE *fp, object_freezer &freezer, FILE *fp2, object_freezer &freezer2, int flag) {
596 int i, j = 0,unique=0; 594 int i, j = 0,unique=0;
597 object *op; 595 object *op;
598 /* first pass - save one-part objects */ 596 /* first pass - save one-part objects */
599 for(i = 0; i < MAP_WIDTH(m); i++) 597 for(i = 0; i < MAP_WIDTH(m); i++)
600 for (j = 0; j < MAP_HEIGHT(m); j++) { 598 for (j = 0; j < MAP_HEIGHT(m); j++) {
610 608
611 if (op->head || op->owner) 609 if (op->head || op->owner)
612 continue; 610 continue;
613 611
614 if (unique || QUERY_FLAG(op, FLAG_UNIQUE)) 612 if (unique || QUERY_FLAG(op, FLAG_UNIQUE))
615 save_object( fp2 , op, 3); 613 save_object( fp2 , freezer2, op, 3);
616 else 614 else
617 if (flag == 0 || 615 if (flag == 0 ||
618 (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) && 616 (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) &&
619 !QUERY_FLAG(op, FLAG_UNPAID)))) 617 !QUERY_FLAG(op, FLAG_UNPAID))))
620 save_object(fp, op, 3); 618 save_object(fp, freezer, op, 3);
621 619
622 } /* for this space */ 620 } /* for this space */
623 } /* for this j */ 621 } /* for this j */
624} 622}
625 623
1033 if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { 1031 if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) {
1034 LOG(llevError, "Can't open %s: %s\n", pathname, strerror_local(errno)); 1032 LOG(llevError, "Can't open %s: %s\n", pathname, strerror_local(errno));
1035 return (NULL); 1033 return (NULL);
1036 } 1034 }
1037 1035
1036 object_thawer thawer (filename);
1037
1038 m = get_linked_map(); 1038 m = get_linked_map();
1039 1039
1040 strcpy (m->path, filename); 1040 strcpy (m->path, filename);
1041 if (load_map_header(fp, m)) { 1041 if (load_map_header(fp, m)) {
1042 LOG(llevError,"Error loading map header for %s, flags=%d\n", 1042 LOG(llevError,"Error loading map header for %s, flags=%d\n",
1047 1047
1048 allocate_map(m); 1048 allocate_map(m);
1049 m->compressed = comp; 1049 m->compressed = comp;
1050 1050
1051 m->in_memory=MAP_LOADING; 1051 m->in_memory=MAP_LOADING;
1052 load_objects (m, fp, flags & (MAP_BLOCK|MAP_STYLE)); 1052 load_objects (m, fp, thawer, flags & (MAP_BLOCK|MAP_STYLE));
1053 close_and_delete(fp, comp); 1053 close_and_delete(fp, comp);
1054 m->in_memory=MAP_IN_MEMORY; 1054 m->in_memory=MAP_IN_MEMORY;
1055 if (!MAP_DIFFICULTY(m)) 1055 if (!MAP_DIFFICULTY(m))
1056 MAP_DIFFICULTY(m)=calculate_difficulty(m); 1056 MAP_DIFFICULTY(m)=calculate_difficulty(m);
1057 set_map_reset_time(m); 1057 set_map_reset_time(m);
1058 if (load_original_map_callback) 1058 INVOKE_MAP (LOAD, m);
1059 load_original_map_callback(m);
1060 return (m); 1059 return (m);
1061} 1060}
1062 1061
1063/* 1062/*
1064 * Loads a map, which has been loaded earlier, from file. 1063 * Loads a map, which has been loaded earlier, from file.
1088 m = load_original_map(buf, 0); 1087 m = load_original_map(buf, 0);
1089 if(m==NULL) return NULL; 1088 if(m==NULL) return NULL;
1090 fix_auto_apply(m); /* Chests which open as default */ 1089 fix_auto_apply(m); /* Chests which open as default */
1091 return m; 1090 return m;
1092 } 1091 }
1093 1092
1093 object_thawer thawer (m->tmpname);
1094 1094
1095 if (load_map_header(fp, m)) { 1095 if (load_map_header(fp, m)) {
1096 LOG(llevError,"Error loading map header for %s (%s)\n", 1096 LOG(llevError,"Error loading map header for %s (%s)\n",
1097 m->path, m->tmpname); 1097 m->path, m->tmpname);
1098 delete_map(m); 1098 delete_map(m);
1101 } 1101 }
1102 m->compressed = comp; 1102 m->compressed = comp;
1103 allocate_map(m); 1103 allocate_map(m);
1104 1104
1105 m->in_memory=MAP_LOADING; 1105 m->in_memory=MAP_LOADING;
1106 load_objects (m, fp, 0); 1106 load_objects (m, fp, thawer, 0);
1107 close_and_delete(fp, comp); 1107 close_and_delete(fp, comp);
1108 m->in_memory=MAP_IN_MEMORY; 1108 m->in_memory=MAP_IN_MEMORY;
1109 if (load_temporary_map_callback) 1109 INVOKE_MAP (SWAPIN, m);
1110 load_temporary_map_callback(m);
1111 return m; 1110 return m;
1112} 1111}
1113 1112
1114/* 1113/*
1115 * Loads a map, which has been loaded earlier, from file. 1114 * Loads a map, which has been loaded earlier, from file.
1126 1125
1127 if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { 1126 if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) {
1128/* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ 1127/* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/
1129 return m; 1128 return m;
1130 } 1129 }
1130
1131 object_thawer thawer (pathname);
1131 1132
1132 if (load_map_header(fp, m)) { 1133 if (load_map_header(fp, m)) {
1133 LOG(llevError,"Error loading map header for overlay %s (%s)\n", 1134 LOG(llevError,"Error loading map header for overlay %s (%s)\n",
1134 m->path, pathname); 1135 m->path, pathname);
1135 delete_map(m); 1136 delete_map(m);
1138 } 1139 }
1139 m->compressed = comp; 1140 m->compressed = comp;
1140 /*allocate_map(m);*/ 1141 /*allocate_map(m);*/
1141 1142
1142 m->in_memory=MAP_LOADING; 1143 m->in_memory=MAP_LOADING;
1143 load_objects (m, fp, MAP_OVERLAY); 1144 load_objects (m, fp, thawer, MAP_OVERLAY);
1144 close_and_delete(fp, comp); 1145 close_and_delete(fp, comp);
1145 m->in_memory=MAP_IN_MEMORY; 1146 m->in_memory=MAP_IN_MEMORY;
1146 return m; 1147 return m;
1147} 1148}
1148 1149
1197 */ 1198 */
1198 LOG(llevDebug, "Can't open unique items file for %s\n", create_items_path(m->path)); 1199 LOG(llevDebug, "Can't open unique items file for %s\n", create_items_path(m->path));
1199 return; 1200 return;
1200 } 1201 }
1201 1202
1203 object_thawer thawer (firstname);
1204
1202 m->in_memory=MAP_LOADING; 1205 m->in_memory=MAP_LOADING;
1203 if (m->tmpname == NULL) /* if we have loaded unique items from */ 1206 if (m->tmpname == NULL) /* if we have loaded unique items from */
1204 delete_unique_items(m); /* original map before, don't duplicate them */ 1207 delete_unique_items(m); /* original map before, don't duplicate them */
1205 load_object(fp, NULL, LO_NOREAD,0); 1208 load_object(fp, thawer, NULL, LO_NOREAD,0);
1206 load_objects (m, fp, 0); 1209 load_objects (m, fp, thawer, 0);
1207 close_and_delete(fp, comp); 1210 close_and_delete(fp, comp);
1208 m->in_memory=MAP_IN_MEMORY; 1211 m->in_memory=MAP_IN_MEMORY;
1209} 1212}
1210 1213
1211 1214
1218 * (this should have been updated when first loaded) 1221 * (this should have been updated when first loaded)
1219 */ 1222 */
1220 1223
1221int new_save_map(mapstruct *m, int flag) { 1224int new_save_map(mapstruct *m, int flag) {
1222 FILE *fp, *fp2; 1225 FILE *fp, *fp2;
1223 char filename[MAX_BUF],buf[MAX_BUF], shop[MAX_BUF]; 1226 char filename[MAX_BUF],buf[MAX_BUF], buf_s[MAX_BUF],
1227 shop[MAX_BUF], filename_s[MAX_BUF];
1224 int i; 1228 int i;
1225 1229
1226 if (flag && !*m->path) { 1230 if (flag && !*m->path) {
1227 LOG(llevError,"Tried to save map without path.\n"); 1231 LOG(llevError,"Tried to save map without path.\n");
1228 return -1; 1232 return -1;
1249 } else { 1253 } else {
1250 if (!m->tmpname) 1254 if (!m->tmpname)
1251 m->tmpname = tempnam_local(settings.tmpdir,NULL); 1255 m->tmpname = tempnam_local(settings.tmpdir,NULL);
1252 strcpy(filename, m->tmpname); 1256 strcpy(filename, m->tmpname);
1253 } 1257 }
1254 LOG(llevDebug,"Saving map %s\n",m->path); 1258 LOG(llevDebug,"Saving map %s to %s\n", m->path, filename);
1255 m->in_memory = MAP_SAVING; 1259 m->in_memory = MAP_SAVING;
1256 1260
1257 unlink (filename); // do not overwrite backups if done via hardlinks 1261 sprintf (filename_s, "%s~", filename);
1258 1262
1259 /* Compress if it isn't a temporary save. Do compress if unique */ 1263 /* Compress if it isn't a temporary save. Do compress if unique */
1260 if (m->compressed && (m->unique || m->templatemap || flag)) { 1264 if (m->compressed && (m->unique || m->templatemap || flag)) {
1261 char buf[MAX_BUF]; 1265 char buf[MAX_BUF];
1262 strcpy(buf, uncomp[m->compressed][2]); 1266 strcpy(buf, uncomp[m->compressed][2]);
1263 strcat(buf, " > "); 1267 strcat(buf, " > ");
1264 strcat(buf, filename); 1268 strcat(buf, filename_s);
1265 fp = popen(buf, "w"); 1269 fp = popen(buf, "w");
1266 } else 1270 } else
1267 fp = fopen(filename, "w"); 1271 fp = fopen(filename_s, "w");
1268 1272
1269 if(fp == NULL) { 1273 if(fp == NULL) {
1270 LOG(llevError, "Cannot write %s: %s\n", filename, strerror_local(errno)); 1274 LOG(llevError, "Cannot write %s: %s\n", filename_s, strerror_local(errno));
1271 return -1; 1275 return -1;
1272 } 1276 }
1277
1278 object_freezer freezer (filename);
1273 1279
1274 /* legacy */ 1280 /* legacy */
1275 fprintf(fp,"arch map\n"); 1281 fprintf(fp,"arch map\n");
1276 if (m->name) fprintf(fp,"name %s\n", m->name); 1282 if (m->name) fprintf(fp,"name %s\n", m->name);
1277 if (!flag) fprintf(fp,"swap_time %d\n", m->swap_time); 1283 if (!flag) fprintf(fp,"swap_time %d\n", m->swap_time);
1325 /* In the game save unique items in the different file, but 1331 /* In the game save unique items in the different file, but
1326 * in the editor save them to the normal map file. 1332 * in the editor save them to the normal map file.
1327 * If unique map, save files in the proper destination (set by 1333 * If unique map, save files in the proper destination (set by
1328 * player) 1334 * player)
1329 */ 1335 */
1330 fp2 = fp; /* save unique items into fp2 */
1331 if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) { 1336 if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) {
1332 sprintf (buf,"%s.v00",create_items_path (m->path)); 1337 sprintf (buf,"%s.v00",create_items_path (m->path));
1338 sprintf (buf_s, "%s~", buf);
1333 if ((fp2 = fopen (buf, "w")) == NULL) { 1339 if ((fp2 = fopen (buf_s, "w")) == NULL) {
1334 LOG(llevError, "Can't open unique items file %s\n", buf); 1340 LOG(llevError, "Can't open unique items file %s\n", buf_s);
1335 } 1341 }
1342
1343 object_freezer freezer2 (buf);
1344
1336 if (flag == 2) 1345 if (flag == 2)
1337 save_objects(m, fp, fp2, 2); 1346 save_objects(m, fp, freezer, fp2, freezer2, 2);
1338 else 1347 else
1339 save_objects (m, fp, fp2, 0); 1348 save_objects (m, fp,freezer, fp2, freezer2, 0);
1340 if (fp2 != NULL) { 1349 if (fp2 != NULL) {
1341 if (ftell (fp2) == 0) { 1350 if (ftell (fp2) == 0) {
1342 fclose (fp2); 1351 fclose (fp2);
1352 rename (buf_s, buf);
1343 unlink (buf); 1353 unlink (buf);
1344 } else { 1354 } else {
1345 fclose (fp2); 1355 fclose (fp2);
1356 rename (buf_s, buf);
1346 chmod (buf, SAVE_MODE); 1357 chmod (buf, SAVE_MODE);
1347 } 1358 }
1348 } 1359 }
1349 } else { /* save same file when not playing, like in editor */ 1360 } else { /* save same file when not playing, like in editor */
1350 save_objects(m, fp, fp, 0); 1361 save_objects(m, fp, freezer, fp, freezer, 0);
1351 } 1362 }
1352 1363
1353 if (m->compressed && (m->unique || m->templatemap || flag)) 1364 if (m->compressed && (m->unique || m->templatemap || flag))
1354 pclose(fp); 1365 pclose(fp);
1355 else 1366 else
1356 fclose(fp); 1367 fclose(fp);
1368
1369 rename (filename_s, filename);
1357 1370
1358 chmod (filename, SAVE_MODE); 1371 chmod (filename, SAVE_MODE);
1359 return 0; 1372 return 0;
1360} 1373}
1361 1374
1674} 1687}
1675 1688
1676void clean_tmp_map(mapstruct *m) { 1689void clean_tmp_map(mapstruct *m) {
1677 if(m->tmpname == NULL) 1690 if(m->tmpname == NULL)
1678 return; 1691 return;
1679 if (clean_temporary_map_callback) 1692 INVOKE_MAP (CLEAN, m);
1680 clean_temporary_map_callback (m);
1681 (void) unlink(m->tmpname); 1693 (void) unlink(m->tmpname);
1682} 1694}
1683 1695
1684void free_all_maps(void) 1696void free_all_maps(void)
1685{ 1697{
1824 flags |= P_IS_ALIVE; 1836 flags |= P_IS_ALIVE;
1825 if (QUERY_FLAG(tmp,FLAG_NO_MAGIC)) 1837 if (QUERY_FLAG(tmp,FLAG_NO_MAGIC))
1826 flags |= P_NO_MAGIC; 1838 flags |= P_NO_MAGIC;
1827 if (QUERY_FLAG(tmp,FLAG_DAMNED)) 1839 if (QUERY_FLAG(tmp,FLAG_DAMNED))
1828 flags |= P_NO_CLERIC; 1840 flags |= P_NO_CLERIC;
1841 if (tmp->type == SAFE_GROUND)
1842 flags |= P_SAFE | P_NO_CLERIC | P_NO_MAGIC;
1829 1843
1830 if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW)) 1844 if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW))
1831 flags |= P_BLOCKSVIEW; 1845 flags |= P_BLOCKSVIEW;
1832 } /* for stack of objects */ 1846 } /* for stack of objects */
1833 1847

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines