1 | /* |
1 | /* |
2 | * static char *rcsid_map_c = |
2 | * static char *rcsid_map_c = |
3 | * "$Id: map.C,v 1.8 2006/08/26 08:44:04 root 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 | |
… | |
… | |
516 | * 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 |
517 | * file pointer. |
517 | * file pointer. |
518 | * mapflags is the same as we get with load_original_map |
518 | * mapflags is the same as we get with load_original_map |
519 | */ |
519 | */ |
520 | |
520 | |
521 | void load_objects (mapstruct *m, FILE *fp, int mapflags) { |
521 | void load_objects (mapstruct *m, FILE *fp, object_thawer &thawer, int mapflags) { |
522 | int i,j,bufstate=LO_NEWFILE; |
522 | int i,j,bufstate=LO_NEWFILE; |
523 | int unique; |
523 | int unique; |
524 | object *op, *prev=NULL,*last_more=NULL, *otmp; |
524 | object *op, *prev=NULL,*last_more=NULL, *otmp; |
525 | |
525 | |
526 | op=get_object(); |
526 | op=get_object(); |
527 | op->map = m; /* To handle buttons correctly */ |
527 | op->map = m; /* To handle buttons correctly */ |
528 | |
528 | |
529 | while((i=load_object(fp,op,bufstate, mapflags))) { |
529 | while((i = load_object (fp, thawer, op, bufstate, mapflags))) { |
530 | /* 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 |
531 | * 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, |
532 | * and then switch to LO_REPEAT for faster loading. |
532 | * and then switch to LO_REPEAT for faster loading. |
533 | */ |
533 | */ |
534 | bufstate = LO_REPEAT; |
534 | bufstate = LO_REPEAT; |
… | |
… | |
588 | /* 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. |
589 | * 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, |
590 | * 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 |
591 | * in order to do map tiling properly. |
591 | * in order to do map tiling properly. |
592 | */ |
592 | */ |
593 | void save_objects (mapstruct *m, FILE *fp, FILE *fp2, int flag) { |
593 | void save_objects (mapstruct *m, FILE *fp, object_freezer &freezer, FILE *fp2, object_freezer &freezer2, int flag) { |
594 | int i, j = 0,unique=0; |
594 | int i, j = 0,unique=0; |
595 | object *op; |
595 | object *op; |
596 | /* first pass - save one-part objects */ |
596 | /* first pass - save one-part objects */ |
597 | for(i = 0; i < MAP_WIDTH(m); i++) |
597 | for(i = 0; i < MAP_WIDTH(m); i++) |
598 | for (j = 0; j < MAP_HEIGHT(m); j++) { |
598 | for (j = 0; j < MAP_HEIGHT(m); j++) { |
… | |
… | |
608 | |
608 | |
609 | if (op->head || op->owner) |
609 | if (op->head || op->owner) |
610 | continue; |
610 | continue; |
611 | |
611 | |
612 | if (unique || QUERY_FLAG(op, FLAG_UNIQUE)) |
612 | if (unique || QUERY_FLAG(op, FLAG_UNIQUE)) |
613 | save_object( fp2 , op, 3); |
613 | save_object( fp2 , freezer2, op, 3); |
614 | else |
614 | else |
615 | if (flag == 0 || |
615 | if (flag == 0 || |
616 | (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) && |
616 | (flag == 2 && (!QUERY_FLAG(op, FLAG_OBJ_ORIGINAL) && |
617 | !QUERY_FLAG(op, FLAG_UNPAID)))) |
617 | !QUERY_FLAG(op, FLAG_UNPAID)))) |
618 | save_object(fp, op, 3); |
618 | save_object(fp, freezer, op, 3); |
619 | |
619 | |
620 | } /* for this space */ |
620 | } /* for this space */ |
621 | } /* for this j */ |
621 | } /* for this j */ |
622 | } |
622 | } |
623 | |
623 | |
… | |
… | |
1031 | if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { |
1031 | if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { |
1032 | 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)); |
1033 | return (NULL); |
1033 | return (NULL); |
1034 | } |
1034 | } |
1035 | |
1035 | |
|
|
1036 | object_thawer thawer (filename); |
|
|
1037 | |
1036 | m = get_linked_map(); |
1038 | m = get_linked_map(); |
1037 | |
1039 | |
1038 | strcpy (m->path, filename); |
1040 | strcpy (m->path, filename); |
1039 | if (load_map_header(fp, m)) { |
1041 | if (load_map_header(fp, m)) { |
1040 | LOG(llevError,"Error loading map header for %s, flags=%d\n", |
1042 | LOG(llevError,"Error loading map header for %s, flags=%d\n", |
… | |
… | |
1045 | |
1047 | |
1046 | allocate_map(m); |
1048 | allocate_map(m); |
1047 | m->compressed = comp; |
1049 | m->compressed = comp; |
1048 | |
1050 | |
1049 | m->in_memory=MAP_LOADING; |
1051 | m->in_memory=MAP_LOADING; |
1050 | load_objects (m, fp, flags & (MAP_BLOCK|MAP_STYLE)); |
1052 | load_objects (m, fp, thawer, flags & (MAP_BLOCK|MAP_STYLE)); |
1051 | close_and_delete(fp, comp); |
1053 | close_and_delete(fp, comp); |
1052 | m->in_memory=MAP_IN_MEMORY; |
1054 | m->in_memory=MAP_IN_MEMORY; |
1053 | if (!MAP_DIFFICULTY(m)) |
1055 | if (!MAP_DIFFICULTY(m)) |
1054 | MAP_DIFFICULTY(m)=calculate_difficulty(m); |
1056 | MAP_DIFFICULTY(m)=calculate_difficulty(m); |
1055 | set_map_reset_time(m); |
1057 | set_map_reset_time(m); |
… | |
… | |
1085 | m = load_original_map(buf, 0); |
1087 | m = load_original_map(buf, 0); |
1086 | if(m==NULL) return NULL; |
1088 | if(m==NULL) return NULL; |
1087 | fix_auto_apply(m); /* Chests which open as default */ |
1089 | fix_auto_apply(m); /* Chests which open as default */ |
1088 | return m; |
1090 | return m; |
1089 | } |
1091 | } |
1090 | |
1092 | |
|
|
1093 | object_thawer thawer (m->tmpname); |
1091 | |
1094 | |
1092 | if (load_map_header(fp, m)) { |
1095 | if (load_map_header(fp, m)) { |
1093 | LOG(llevError,"Error loading map header for %s (%s)\n", |
1096 | LOG(llevError,"Error loading map header for %s (%s)\n", |
1094 | m->path, m->tmpname); |
1097 | m->path, m->tmpname); |
1095 | delete_map(m); |
1098 | delete_map(m); |
… | |
… | |
1098 | } |
1101 | } |
1099 | m->compressed = comp; |
1102 | m->compressed = comp; |
1100 | allocate_map(m); |
1103 | allocate_map(m); |
1101 | |
1104 | |
1102 | m->in_memory=MAP_LOADING; |
1105 | m->in_memory=MAP_LOADING; |
1103 | load_objects (m, fp, 0); |
1106 | load_objects (m, fp, thawer, 0); |
1104 | close_and_delete(fp, comp); |
1107 | close_and_delete(fp, comp); |
1105 | m->in_memory=MAP_IN_MEMORY; |
1108 | m->in_memory=MAP_IN_MEMORY; |
1106 | INVOKE_MAP (SWAPIN, m); |
1109 | INVOKE_MAP (SWAPIN, m); |
1107 | return m; |
1110 | return m; |
1108 | } |
1111 | } |
… | |
… | |
1122 | |
1125 | |
1123 | if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { |
1126 | if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { |
1124 | /* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ |
1127 | /* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ |
1125 | return m; |
1128 | return m; |
1126 | } |
1129 | } |
|
|
1130 | |
|
|
1131 | object_thawer thawer (pathname); |
1127 | |
1132 | |
1128 | if (load_map_header(fp, m)) { |
1133 | if (load_map_header(fp, m)) { |
1129 | LOG(llevError,"Error loading map header for overlay %s (%s)\n", |
1134 | LOG(llevError,"Error loading map header for overlay %s (%s)\n", |
1130 | m->path, pathname); |
1135 | m->path, pathname); |
1131 | delete_map(m); |
1136 | delete_map(m); |
… | |
… | |
1134 | } |
1139 | } |
1135 | m->compressed = comp; |
1140 | m->compressed = comp; |
1136 | /*allocate_map(m);*/ |
1141 | /*allocate_map(m);*/ |
1137 | |
1142 | |
1138 | m->in_memory=MAP_LOADING; |
1143 | m->in_memory=MAP_LOADING; |
1139 | load_objects (m, fp, MAP_OVERLAY); |
1144 | load_objects (m, fp, thawer, MAP_OVERLAY); |
1140 | close_and_delete(fp, comp); |
1145 | close_and_delete(fp, comp); |
1141 | m->in_memory=MAP_IN_MEMORY; |
1146 | m->in_memory=MAP_IN_MEMORY; |
1142 | return m; |
1147 | return m; |
1143 | } |
1148 | } |
1144 | |
1149 | |
… | |
… | |
1193 | */ |
1198 | */ |
1194 | 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)); |
1195 | return; |
1200 | return; |
1196 | } |
1201 | } |
1197 | |
1202 | |
|
|
1203 | object_thawer thawer (firstname); |
|
|
1204 | |
1198 | m->in_memory=MAP_LOADING; |
1205 | m->in_memory=MAP_LOADING; |
1199 | if (m->tmpname == NULL) /* if we have loaded unique items from */ |
1206 | if (m->tmpname == NULL) /* if we have loaded unique items from */ |
1200 | delete_unique_items(m); /* original map before, don't duplicate them */ |
1207 | delete_unique_items(m); /* original map before, don't duplicate them */ |
1201 | load_object(fp, NULL, LO_NOREAD,0); |
1208 | load_object(fp, thawer, NULL, LO_NOREAD,0); |
1202 | load_objects (m, fp, 0); |
1209 | load_objects (m, fp, thawer, 0); |
1203 | close_and_delete(fp, comp); |
1210 | close_and_delete(fp, comp); |
1204 | m->in_memory=MAP_IN_MEMORY; |
1211 | m->in_memory=MAP_IN_MEMORY; |
1205 | } |
1212 | } |
1206 | |
1213 | |
1207 | |
1214 | |
… | |
… | |
1265 | |
1272 | |
1266 | if(fp == NULL) { |
1273 | if(fp == NULL) { |
1267 | LOG(llevError, "Cannot write %s: %s\n", filename_s, strerror_local(errno)); |
1274 | LOG(llevError, "Cannot write %s: %s\n", filename_s, strerror_local(errno)); |
1268 | return -1; |
1275 | return -1; |
1269 | } |
1276 | } |
|
|
1277 | |
|
|
1278 | object_freezer freezer (filename); |
1270 | |
1279 | |
1271 | /* legacy */ |
1280 | /* legacy */ |
1272 | fprintf(fp,"arch map\n"); |
1281 | fprintf(fp,"arch map\n"); |
1273 | if (m->name) fprintf(fp,"name %s\n", m->name); |
1282 | if (m->name) fprintf(fp,"name %s\n", m->name); |
1274 | if (!flag) fprintf(fp,"swap_time %d\n", m->swap_time); |
1283 | if (!flag) fprintf(fp,"swap_time %d\n", m->swap_time); |
… | |
… | |
1328 | sprintf (buf,"%s.v00",create_items_path (m->path)); |
1337 | sprintf (buf,"%s.v00",create_items_path (m->path)); |
1329 | sprintf (buf_s, "%s~", buf); |
1338 | sprintf (buf_s, "%s~", buf); |
1330 | if ((fp2 = fopen (buf_s, "w")) == NULL) { |
1339 | if ((fp2 = fopen (buf_s, "w")) == NULL) { |
1331 | LOG(llevError, "Can't open unique items file %s\n", buf_s); |
1340 | LOG(llevError, "Can't open unique items file %s\n", buf_s); |
1332 | } |
1341 | } |
|
|
1342 | |
|
|
1343 | object_freezer freezer2 (buf); |
|
|
1344 | |
1333 | if (flag == 2) |
1345 | if (flag == 2) |
1334 | save_objects(m, fp, fp2, 2); |
1346 | save_objects(m, fp, freezer, fp2, freezer2, 2); |
1335 | else |
1347 | else |
1336 | save_objects (m, fp, fp2, 0); |
1348 | save_objects (m, fp,freezer, fp2, freezer2, 0); |
1337 | if (fp2 != NULL) { |
1349 | if (fp2 != NULL) { |
1338 | if (ftell (fp2) == 0) { |
1350 | if (ftell (fp2) == 0) { |
1339 | fclose (fp2); |
1351 | fclose (fp2); |
1340 | rename (buf_s, buf); |
1352 | rename (buf_s, buf); |
1341 | unlink (buf); |
1353 | unlink (buf); |
… | |
… | |
1344 | rename (buf_s, buf); |
1356 | rename (buf_s, buf); |
1345 | chmod (buf, SAVE_MODE); |
1357 | chmod (buf, SAVE_MODE); |
1346 | } |
1358 | } |
1347 | } |
1359 | } |
1348 | } else { /* save same file when not playing, like in editor */ |
1360 | } else { /* save same file when not playing, like in editor */ |
1349 | save_objects(m, fp, fp, 0); |
1361 | save_objects(m, fp, freezer, fp, freezer, 0); |
1350 | } |
1362 | } |
1351 | |
1363 | |
1352 | if (m->compressed && (m->unique || m->templatemap || flag)) |
1364 | if (m->compressed && (m->unique || m->templatemap || flag)) |
1353 | pclose(fp); |
1365 | pclose(fp); |
1354 | else |
1366 | else |