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.8 2006/08/26 08:44:04 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 | |
41 | extern int nrofallocobjects,nroffreeobjects; |
41 | extern int nrofallocobjects,nroffreeobjects; |
42 | |
|
|
43 | void (*load_original_map_callback)(mapstruct *map); |
|
|
44 | void (*load_temporary_map_callback)(mapstruct *map); |
|
|
45 | void (*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 | /* |
… | |
… | |
1053 | close_and_delete(fp, comp); |
1051 | close_and_delete(fp, comp); |
1054 | m->in_memory=MAP_IN_MEMORY; |
1052 | m->in_memory=MAP_IN_MEMORY; |
1055 | if (!MAP_DIFFICULTY(m)) |
1053 | if (!MAP_DIFFICULTY(m)) |
1056 | MAP_DIFFICULTY(m)=calculate_difficulty(m); |
1054 | MAP_DIFFICULTY(m)=calculate_difficulty(m); |
1057 | set_map_reset_time(m); |
1055 | set_map_reset_time(m); |
1058 | if (load_original_map_callback) |
1056 | INVOKE_MAP (LOAD, m); |
1059 | load_original_map_callback(m); |
|
|
1060 | return (m); |
1057 | return (m); |
1061 | } |
1058 | } |
1062 | |
1059 | |
1063 | /* |
1060 | /* |
1064 | * Loads a map, which has been loaded earlier, from file. |
1061 | * Loads a map, which has been loaded earlier, from file. |
… | |
… | |
1104 | |
1101 | |
1105 | m->in_memory=MAP_LOADING; |
1102 | m->in_memory=MAP_LOADING; |
1106 | load_objects (m, fp, 0); |
1103 | load_objects (m, fp, 0); |
1107 | close_and_delete(fp, comp); |
1104 | close_and_delete(fp, comp); |
1108 | m->in_memory=MAP_IN_MEMORY; |
1105 | m->in_memory=MAP_IN_MEMORY; |
1109 | if (load_temporary_map_callback) |
1106 | INVOKE_MAP (SWAPIN, m); |
1110 | load_temporary_map_callback(m); |
|
|
1111 | return m; |
1107 | return m; |
1112 | } |
1108 | } |
1113 | |
1109 | |
1114 | /* |
1110 | /* |
1115 | * Loads a map, which has been loaded earlier, from file. |
1111 | * Loads a map, which has been loaded earlier, from file. |
… | |
… | |
1218 | * (this should have been updated when first loaded) |
1214 | * (this should have been updated when first loaded) |
1219 | */ |
1215 | */ |
1220 | |
1216 | |
1221 | int new_save_map(mapstruct *m, int flag) { |
1217 | int new_save_map(mapstruct *m, int flag) { |
1222 | FILE *fp, *fp2; |
1218 | FILE *fp, *fp2; |
1223 | char filename[MAX_BUF],buf[MAX_BUF], shop[MAX_BUF]; |
1219 | char filename[MAX_BUF],buf[MAX_BUF], buf_s[MAX_BUF], |
|
|
1220 | shop[MAX_BUF], filename_s[MAX_BUF]; |
1224 | int i; |
1221 | int i; |
1225 | |
1222 | |
1226 | if (flag && !*m->path) { |
1223 | if (flag && !*m->path) { |
1227 | LOG(llevError,"Tried to save map without path.\n"); |
1224 | LOG(llevError,"Tried to save map without path.\n"); |
1228 | return -1; |
1225 | return -1; |
… | |
… | |
1249 | } else { |
1246 | } else { |
1250 | if (!m->tmpname) |
1247 | if (!m->tmpname) |
1251 | m->tmpname = tempnam_local(settings.tmpdir,NULL); |
1248 | m->tmpname = tempnam_local(settings.tmpdir,NULL); |
1252 | strcpy(filename, m->tmpname); |
1249 | strcpy(filename, m->tmpname); |
1253 | } |
1250 | } |
1254 | LOG(llevDebug,"Saving map %s\n",m->path); |
1251 | LOG(llevDebug,"Saving map %s to %s\n", m->path, filename); |
1255 | m->in_memory = MAP_SAVING; |
1252 | m->in_memory = MAP_SAVING; |
1256 | |
1253 | |
1257 | unlink (filename); // do not overwrite backups if done via hardlinks |
1254 | sprintf (filename_s, "%s~", filename); |
1258 | |
1255 | |
1259 | /* Compress if it isn't a temporary save. Do compress if unique */ |
1256 | /* Compress if it isn't a temporary save. Do compress if unique */ |
1260 | if (m->compressed && (m->unique || m->templatemap || flag)) { |
1257 | if (m->compressed && (m->unique || m->templatemap || flag)) { |
1261 | char buf[MAX_BUF]; |
1258 | char buf[MAX_BUF]; |
1262 | strcpy(buf, uncomp[m->compressed][2]); |
1259 | strcpy(buf, uncomp[m->compressed][2]); |
1263 | strcat(buf, " > "); |
1260 | strcat(buf, " > "); |
1264 | strcat(buf, filename); |
1261 | strcat(buf, filename_s); |
1265 | fp = popen(buf, "w"); |
1262 | fp = popen(buf, "w"); |
1266 | } else |
1263 | } else |
1267 | fp = fopen(filename, "w"); |
1264 | fp = fopen(filename_s, "w"); |
1268 | |
1265 | |
1269 | if(fp == NULL) { |
1266 | if(fp == NULL) { |
1270 | LOG(llevError, "Cannot write %s: %s\n", filename, strerror_local(errno)); |
1267 | LOG(llevError, "Cannot write %s: %s\n", filename_s, strerror_local(errno)); |
1271 | return -1; |
1268 | return -1; |
1272 | } |
1269 | } |
1273 | |
1270 | |
1274 | /* legacy */ |
1271 | /* legacy */ |
1275 | fprintf(fp,"arch map\n"); |
1272 | fprintf(fp,"arch map\n"); |
… | |
… | |
1325 | /* In the game save unique items in the different file, but |
1322 | /* In the game save unique items in the different file, but |
1326 | * in the editor save them to the normal map file. |
1323 | * in the editor save them to the normal map file. |
1327 | * If unique map, save files in the proper destination (set by |
1324 | * If unique map, save files in the proper destination (set by |
1328 | * player) |
1325 | * player) |
1329 | */ |
1326 | */ |
1330 | fp2 = fp; /* save unique items into fp2 */ |
|
|
1331 | if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) { |
1327 | if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) { |
1332 | sprintf (buf,"%s.v00",create_items_path (m->path)); |
1328 | sprintf (buf,"%s.v00",create_items_path (m->path)); |
|
|
1329 | sprintf (buf_s, "%s~", buf); |
1333 | if ((fp2 = fopen (buf, "w")) == NULL) { |
1330 | if ((fp2 = fopen (buf_s, "w")) == NULL) { |
1334 | LOG(llevError, "Can't open unique items file %s\n", buf); |
1331 | LOG(llevError, "Can't open unique items file %s\n", buf_s); |
1335 | } |
1332 | } |
1336 | if (flag == 2) |
1333 | if (flag == 2) |
1337 | save_objects(m, fp, fp2, 2); |
1334 | save_objects(m, fp, fp2, 2); |
1338 | else |
1335 | else |
1339 | save_objects (m, fp, fp2, 0); |
1336 | save_objects (m, fp, fp2, 0); |
1340 | if (fp2 != NULL) { |
1337 | if (fp2 != NULL) { |
1341 | if (ftell (fp2) == 0) { |
1338 | if (ftell (fp2) == 0) { |
1342 | fclose (fp2); |
1339 | fclose (fp2); |
|
|
1340 | rename (buf_s, buf); |
1343 | unlink (buf); |
1341 | unlink (buf); |
1344 | } else { |
1342 | } else { |
1345 | fclose (fp2); |
1343 | fclose (fp2); |
|
|
1344 | rename (buf_s, buf); |
1346 | chmod (buf, SAVE_MODE); |
1345 | chmod (buf, SAVE_MODE); |
1347 | } |
1346 | } |
1348 | } |
1347 | } |
1349 | } else { /* save same file when not playing, like in editor */ |
1348 | } else { /* save same file when not playing, like in editor */ |
1350 | save_objects(m, fp, fp, 0); |
1349 | save_objects(m, fp, fp, 0); |
… | |
… | |
1352 | |
1351 | |
1353 | if (m->compressed && (m->unique || m->templatemap || flag)) |
1352 | if (m->compressed && (m->unique || m->templatemap || flag)) |
1354 | pclose(fp); |
1353 | pclose(fp); |
1355 | else |
1354 | else |
1356 | fclose(fp); |
1355 | fclose(fp); |
|
|
1356 | |
|
|
1357 | rename (filename_s, filename); |
1357 | |
1358 | |
1358 | chmod (filename, SAVE_MODE); |
1359 | chmod (filename, SAVE_MODE); |
1359 | return 0; |
1360 | return 0; |
1360 | } |
1361 | } |
1361 | |
1362 | |
… | |
… | |
1674 | } |
1675 | } |
1675 | |
1676 | |
1676 | void clean_tmp_map(mapstruct *m) { |
1677 | void clean_tmp_map(mapstruct *m) { |
1677 | if(m->tmpname == NULL) |
1678 | if(m->tmpname == NULL) |
1678 | return; |
1679 | return; |
1679 | if (clean_temporary_map_callback) |
1680 | INVOKE_MAP (CLEAN, m); |
1680 | clean_temporary_map_callback (m); |
|
|
1681 | (void) unlink(m->tmpname); |
1681 | (void) unlink(m->tmpname); |
1682 | } |
1682 | } |
1683 | |
1683 | |
1684 | void free_all_maps(void) |
1684 | void free_all_maps(void) |
1685 | { |
1685 | { |
… | |
… | |
1824 | flags |= P_IS_ALIVE; |
1824 | flags |= P_IS_ALIVE; |
1825 | if (QUERY_FLAG(tmp,FLAG_NO_MAGIC)) |
1825 | if (QUERY_FLAG(tmp,FLAG_NO_MAGIC)) |
1826 | flags |= P_NO_MAGIC; |
1826 | flags |= P_NO_MAGIC; |
1827 | if (QUERY_FLAG(tmp,FLAG_DAMNED)) |
1827 | if (QUERY_FLAG(tmp,FLAG_DAMNED)) |
1828 | flags |= P_NO_CLERIC; |
1828 | flags |= P_NO_CLERIC; |
|
|
1829 | if (tmp->type == SAFE_GROUND) |
|
|
1830 | flags |= P_SAFE | P_NO_CLERIC | P_NO_MAGIC; |
1829 | |
1831 | |
1830 | if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW)) |
1832 | if (QUERY_FLAG(tmp,FLAG_BLOCKSVIEW)) |
1831 | flags |= P_BLOCKSVIEW; |
1833 | flags |= P_BLOCKSVIEW; |
1832 | } /* for stack of objects */ |
1834 | } /* for stack of objects */ |
1833 | |
1835 | |