1 | /* |
1 | /* |
2 | * static char *rcsid_map_c = |
2 | * static char *rcsid_map_c = |
3 | * "$Id: map.C,v 1.11 2006/08/28 16:12:59 root Exp $"; |
3 | * "$Id: map.C,v 1.24 2006/09/04 16:46:32 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 | |
… | |
… | |
173 | * Can not use strcat because we need to cycle through |
173 | * Can not use strcat because we need to cycle through |
174 | * all the names. |
174 | * all the names. |
175 | */ |
175 | */ |
176 | endbuf = buf + strlen(buf); |
176 | endbuf = buf + strlen(buf); |
177 | |
177 | |
178 | for (i = 0; i < NROF_COMPRESS_METHODS; i++) { |
|
|
179 | if (uncomp[i][0]) |
|
|
180 | strcpy(endbuf, uncomp[i][0]); |
|
|
181 | else |
|
|
182 | *endbuf = '\0'; |
|
|
183 | if (!stat (buf, &statbuf)) |
178 | if (stat (buf, &statbuf)) |
184 | break; |
|
|
185 | } |
|
|
186 | if (i == NROF_COMPRESS_METHODS) |
|
|
187 | return (-1); |
179 | return -1; |
188 | if (!S_ISREG (statbuf.st_mode)) |
180 | if (!S_ISREG (statbuf.st_mode)) |
189 | return (-1); |
181 | return (-1); |
190 | |
182 | |
191 | if (((statbuf.st_mode & S_IRGRP) && getegid() == statbuf.st_gid) || |
183 | if (((statbuf.st_mode & S_IRGRP) && getegid() == statbuf.st_gid) || |
192 | ((statbuf.st_mode & S_IRUSR) && geteuid() == statbuf.st_uid) || |
184 | ((statbuf.st_mode & S_IRUSR) && geteuid() == statbuf.st_uid) || |
… | |
… | |
490 | op->x += tmp->x; |
482 | op->x += tmp->x; |
491 | op->y += tmp->y; |
483 | op->y += tmp->y; |
492 | op->head = tmp; |
484 | op->head = tmp; |
493 | op->map = m; |
485 | op->map = m; |
494 | last->more = op; |
486 | last->more = op; |
495 | if (tmp->name != op->name) { |
|
|
496 | if (op->name) free_string(op->name); |
|
|
497 | op->name = add_string(tmp->name); |
487 | op->name = tmp->name; |
498 | } |
|
|
499 | if (tmp->title != op->title) { |
|
|
500 | if (op->title) free_string(op->title); |
|
|
501 | op->title = add_string(tmp->title); |
488 | op->title = tmp->title; |
502 | } |
|
|
503 | /* we could link all the parts onto tmp, and then just |
489 | /* we could link all the parts onto tmp, and then just |
504 | * call insert_ob_in_map once, but the effect is the same, |
490 | * call insert_ob_in_map once, but the effect is the same, |
505 | * as insert_ob_in_map will call itself with each part, and |
491 | * as insert_ob_in_map will call itself with each part, and |
506 | * the coding is simpler to just to it here with each part. |
492 | * the coding is simpler to just to it here with each part. |
507 | */ |
493 | */ |
508 | insert_ob_in_map(op, op->map, tmp,INS_NO_MERGE|INS_ABOVE_FLOOR_ONLY|INS_NO_WALK_ON); |
494 | insert_ob_in_map(op, op->map, tmp,INS_NO_MERGE|INS_ABOVE_FLOOR_ONLY|INS_NO_WALK_ON); |
509 | } /* for at = tmp->arch->more */ |
495 | } /* for at = tmp->arch->more */ |
510 | } /* for objects on this space */ |
496 | } /* for objects on this space */ |
511 | } |
497 | } |
512 | |
498 | |
513 | |
|
|
514 | |
|
|
515 | /* |
499 | /* |
516 | * Loads (ands parses) the objects into a given map from the specified |
500 | * Loads (ands parses) the objects into a given map from the specified |
517 | * file pointer. |
501 | * file pointer. |
518 | * mapflags is the same as we get with load_original_map |
502 | * mapflags is the same as we get with load_original_map |
519 | */ |
503 | */ |
520 | |
504 | void |
521 | void load_objects (mapstruct *m, object_thawer &fp, int mapflags) { |
505 | load_objects (mapstruct *m, object_thawer &fp, int mapflags) |
522 | int i,j,bufstate=LO_NEWFILE; |
506 | { |
|
|
507 | int i, j; |
523 | int unique; |
508 | int unique; |
524 | object *op, *prev=NULL,*last_more=NULL, *otmp; |
509 | object *op, *prev = NULL, *last_more = NULL, *otmp; |
525 | |
510 | |
526 | op=get_object(); |
511 | op = get_object (); |
527 | op->map = m; /* To handle buttons correctly */ |
512 | op->map = m; /* To handle buttons correctly */ |
528 | |
513 | |
529 | while((i = load_object (fp, op, bufstate, mapflags))) { |
514 | while ((i = load_object (fp, op, mapflags))) |
530 | /* Since the loading of the map header does not load an object |
515 | { |
531 | * anymore, we need to pass LO_NEWFILE for the first object loaded, |
|
|
532 | * and then switch to LO_REPEAT for faster loading. |
|
|
533 | */ |
|
|
534 | bufstate = LO_REPEAT; |
|
|
535 | |
|
|
536 | /* if the archetype for the object is null, means that we |
516 | /* if the archetype for the object is null, means that we |
537 | * got an invalid object. Don't do anything with it - the game |
517 | * got an invalid object. Don't do anything with it - the game |
538 | * or editor will not be able to do anything with it either. |
518 | * or editor will not be able to do anything with it either. |
539 | */ |
519 | */ |
540 | if (op->arch==NULL) { |
520 | if (op->arch == NULL) |
|
|
521 | { |
541 | LOG(llevDebug,"Discarding object without arch: %s\n", op->name?op->name:"(null)"); |
522 | LOG (llevDebug, "Discarding object without arch: %s\n", |
|
|
523 | op->name ? (const char *) op->name : "(null)"); |
542 | continue; |
524 | continue; |
|
|
525 | } |
|
|
526 | |
|
|
527 | |
|
|
528 | switch (i) |
543 | } |
529 | { |
544 | |
|
|
545 | |
|
|
546 | switch(i) { |
|
|
547 | case LL_NORMAL: |
530 | case LL_NORMAL: |
548 | /* if we are loading an overlay, put the floors on the bottom */ |
531 | /* if we are loading an overlay, put the floors on the bottom */ |
549 | if ((QUERY_FLAG(op, FLAG_IS_FLOOR) || |
532 | if ((QUERY_FLAG (op, FLAG_IS_FLOOR) || |
550 | QUERY_FLAG(op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) |
533 | QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) |
551 | insert_ob_in_map(op,m,op,INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY | INS_MAP_LOAD); |
534 | insert_ob_in_map (op, m, op, |
|
|
535 | INS_NO_MERGE | INS_NO_WALK_ON | |
|
|
536 | INS_ABOVE_FLOOR_ONLY | INS_MAP_LOAD); |
552 | else |
537 | else |
553 | insert_ob_in_map(op,m,op,INS_NO_MERGE | INS_NO_WALK_ON | INS_ON_TOP | INS_MAP_LOAD); |
538 | insert_ob_in_map (op, m, op, |
|
|
539 | INS_NO_MERGE | INS_NO_WALK_ON | INS_ON_TOP | |
|
|
540 | INS_MAP_LOAD); |
554 | |
541 | |
555 | if (op->inv) |
542 | if (op->inv) |
556 | sum_weight(op); |
543 | sum_weight (op); |
557 | |
544 | |
558 | prev=op,last_more=op; |
545 | prev = op, last_more = op; |
559 | break; |
546 | break; |
560 | |
547 | |
561 | case LL_MORE: |
548 | case LL_MORE: |
562 | insert_ob_in_map(op,m, op, INS_NO_MERGE | INS_NO_WALK_ON | INS_ABOVE_FLOOR_ONLY); |
549 | insert_ob_in_map (op, m, op, |
|
|
550 | INS_NO_MERGE | INS_NO_WALK_ON | |
|
|
551 | INS_ABOVE_FLOOR_ONLY); |
563 | op->head=prev,last_more->more=op,last_more=op; |
552 | op->head = prev, last_more->more = op, last_more = op; |
564 | break; |
553 | break; |
565 | } |
554 | } |
|
|
555 | |
566 | if (mapflags & MAP_STYLE) { |
556 | if (mapflags & MAP_STYLE) |
567 | remove_from_active_list(op); |
557 | remove_from_active_list (op); |
568 | } |
558 | |
569 | op=get_object(); |
559 | op = get_object (); |
570 | op->map = m; |
560 | op->map = m; |
571 | } |
561 | } |
|
|
562 | |
572 | for (i=0;i<m->width;i++){ |
563 | for (i = 0; i < m->width; i++) |
|
|
564 | { |
573 | for (j=0;j<m->height;j++){ |
565 | for (j = 0; j < m->height; j++) |
|
|
566 | { |
574 | unique =0; |
567 | unique = 0; |
575 | /* check for unique items, or unique squares */ |
568 | /* check for unique items, or unique squares */ |
576 | for (otmp = get_map_ob(m, i, j); otmp; otmp = otmp->above) { |
569 | for (otmp = get_map_ob (m, i, j); otmp; otmp = otmp->above) |
577 | if (QUERY_FLAG(otmp, FLAG_UNIQUE) || QUERY_FLAG(otmp, FLAG_OBJ_SAVE_ON_OVL)) |
570 | { |
|
|
571 | if (QUERY_FLAG (otmp, FLAG_UNIQUE) |
|
|
572 | || QUERY_FLAG (otmp, FLAG_OBJ_SAVE_ON_OVL)) |
578 | unique = 1; |
573 | unique = 1; |
579 | if (!(mapflags & (MAP_OVERLAY|MAP_PLAYER_UNIQUE) || unique)) |
574 | if (!(mapflags & (MAP_OVERLAY | MAP_PLAYER_UNIQUE) || unique)) |
580 | SET_FLAG(otmp, FLAG_OBJ_ORIGINAL); |
575 | SET_FLAG (otmp, FLAG_OBJ_ORIGINAL); |
581 | } |
576 | } |
582 | } |
577 | } |
583 | } |
578 | } |
|
|
579 | |
584 | free_object(op); |
580 | free_object (op); |
585 | link_multipart_objects(m); |
581 | link_multipart_objects (m); |
586 | } |
582 | } |
587 | |
583 | |
588 | /* This saves all the objects on the map in a non destructive fashion. |
584 | /* 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, |
585 | * 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 |
586 | * and we only save the head of multi part objects - this is needed |
… | |
… | |
626 | * Modified to no longer take a path option which was not being |
622 | * Modified to no longer take a path option which was not being |
627 | * used anyways. MSW 2001-07-01 |
623 | * used anyways. MSW 2001-07-01 |
628 | */ |
624 | */ |
629 | |
625 | |
630 | mapstruct *get_linked_map(void) { |
626 | mapstruct *get_linked_map(void) { |
631 | mapstruct *map=(mapstruct *) calloc(1,sizeof(mapstruct)); |
627 | mapstruct *map = new mapstruct; |
632 | mapstruct *mp; |
628 | mapstruct *mp; |
633 | |
|
|
634 | if(map==NULL) |
|
|
635 | fatal(OUT_OF_MEMORY); |
|
|
636 | |
629 | |
637 | for(mp=first_map;mp!=NULL&&mp->next!=NULL;mp=mp->next); |
630 | for(mp=first_map;mp!=NULL&&mp->next!=NULL;mp=mp->next); |
638 | if(mp==NULL) |
631 | if(mp==NULL) |
639 | first_map=map; |
632 | first_map=map; |
640 | else |
633 | else |
… | |
… | |
823 | value = NULL; |
816 | value = NULL; |
824 | break; |
817 | break; |
825 | } |
818 | } |
826 | } |
819 | } |
827 | } |
820 | } |
|
|
821 | |
828 | if (!end) { |
822 | if (!end) { |
829 | LOG(llevError, "Error loading map header - did not find a newline - perhaps file is truncated? Buf=%s\n", |
823 | LOG(llevError, "Error loading map header - did not find a newline - perhaps file is truncated? Buf=%s\n", |
830 | buf); |
824 | buf); |
831 | return 1; |
825 | return 1; |
832 | } |
826 | } |
833 | |
|
|
834 | |
827 | |
835 | /* key is the field name, value is what it should be set |
828 | /* key is the field name, value is what it should be set |
836 | * to. We've already done the work to null terminate key, |
829 | * to. We've already done the work to null terminate key, |
837 | * and strip off any leading spaces for both of these. |
830 | * and strip off any leading spaces for both of these. |
838 | * We have not touched the newline at the end of the line - |
831 | * We have not touched the newline at the end of the line - |
… | |
… | |
895 | * for compatibility reasons. The new values (second) are |
888 | * for compatibility reasons. The new values (second) are |
896 | * what really should be used. |
889 | * what really should be used. |
897 | */ |
890 | */ |
898 | else if (!strcmp(key,"oid")) { |
891 | else if (!strcmp(key,"oid")) { |
899 | fp.get (m, atoi(value)); |
892 | fp.get (m, atoi(value)); |
|
|
893 | } else if (!strcmp(key, "attach")) { |
|
|
894 | m->attach = value; |
900 | } else if (!strcmp(key,"hp") || !strcmp(key, "enter_x")) { |
895 | } else if (!strcmp(key,"hp") || !strcmp(key, "enter_x")) { |
901 | m->enter_x = atoi(value); |
896 | m->enter_x = atoi(value); |
902 | } else if (!strcmp(key,"sp") || !strcmp(key, "enter_y")) { |
897 | } else if (!strcmp(key,"sp") || !strcmp(key, "enter_y")) { |
903 | m->enter_y = atoi(value); |
898 | m->enter_y = atoi(value); |
904 | } else if (!strcmp(key,"x") || !strcmp(key, "width")) { |
899 | } else if (!strcmp(key,"x") || !strcmp(key, "width")) { |
… | |
… | |
947 | m->winddir = atoi(value); |
942 | m->winddir = atoi(value); |
948 | } else if (!strcmp(key, "sky")) { |
943 | } else if (!strcmp(key, "sky")) { |
949 | m->sky = atoi(value); |
944 | m->sky = atoi(value); |
950 | } else if (!strcmp(key, "nosmooth")) { |
945 | } else if (!strcmp(key, "nosmooth")) { |
951 | m->nosmooth = atoi(value); |
946 | m->nosmooth = atoi(value); |
952 | } else if (!strcmp(key, "safe_map")) { |
|
|
953 | m->safe_map = atoi(value); |
|
|
954 | } |
947 | } |
955 | else if (!strncmp(key,"tile_path_", 10)) { |
948 | else if (!strncmp(key,"tile_path_", 10)) { |
956 | int tile=atoi(key+10); |
949 | int tile=atoi(key+10); |
957 | |
950 | |
958 | if (tile<1 || tile>4) { |
951 | if (tile<1 || tile>4) { |
… | |
… | |
1015 | * MAP_STYLE: style map - don't add active objects, don't add to server |
1008 | * MAP_STYLE: style map - don't add active objects, don't add to server |
1016 | * managed map list. |
1009 | * managed map list. |
1017 | */ |
1010 | */ |
1018 | |
1011 | |
1019 | mapstruct *load_original_map(const char *filename, int flags) { |
1012 | mapstruct *load_original_map(const char *filename, int flags) { |
1020 | FILE *fp; |
|
|
1021 | mapstruct *m; |
1013 | mapstruct *m; |
1022 | int comp; |
|
|
1023 | char pathname[MAX_BUF]; |
1014 | char pathname[MAX_BUF]; |
1024 | |
1015 | |
1025 | LOG(llevDebug, "load_original_map: %s (%x)\n", filename,flags); |
|
|
1026 | if (flags & MAP_PLAYER_UNIQUE) |
1016 | if (flags & MAP_PLAYER_UNIQUE) |
1027 | strcpy(pathname, filename); |
1017 | strcpy(pathname, filename); |
1028 | else if (flags & MAP_OVERLAY) |
1018 | else if (flags & MAP_OVERLAY) |
1029 | strcpy(pathname, create_overlay_pathname(filename)); |
1019 | strcpy(pathname, create_overlay_pathname(filename)); |
1030 | else |
1020 | else |
1031 | strcpy(pathname, create_pathname(filename)); |
1021 | strcpy(pathname, create_pathname(filename)); |
1032 | |
1022 | |
1033 | if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { |
1023 | LOG(llevDebug, "load_original_map(%x): %s (%s)\n", flags, filename, pathname); |
1034 | LOG(llevError, "Can't open %s: %s\n", pathname, strerror_local(errno)); |
|
|
1035 | return (NULL); |
|
|
1036 | } |
|
|
1037 | |
1024 | |
1038 | object_thawer thawer (fp, filename); |
1025 | object_thawer thawer (pathname); |
|
|
1026 | |
|
|
1027 | if (!thawer) |
|
|
1028 | return 0; |
1039 | |
1029 | |
1040 | m = get_linked_map(); |
1030 | m = get_linked_map(); |
1041 | |
1031 | |
1042 | strcpy (m->path, filename); |
1032 | strcpy (m->path, filename); |
1043 | if (load_map_header(thawer, m)) { |
1033 | if (load_map_header(thawer, m)) { |
… | |
… | |
1049 | |
1039 | |
1050 | allocate_map(m); |
1040 | allocate_map(m); |
1051 | |
1041 | |
1052 | m->in_memory=MAP_LOADING; |
1042 | m->in_memory=MAP_LOADING; |
1053 | load_objects (m, thawer, flags & (MAP_BLOCK|MAP_STYLE)); |
1043 | load_objects (m, thawer, flags & (MAP_BLOCK|MAP_STYLE)); |
1054 | close_and_delete(fp, comp); |
1044 | |
1055 | m->in_memory=MAP_IN_MEMORY; |
1045 | m->in_memory=MAP_IN_MEMORY; |
1056 | if (!MAP_DIFFICULTY(m)) |
1046 | if (!MAP_DIFFICULTY(m)) |
1057 | MAP_DIFFICULTY(m)=calculate_difficulty(m); |
1047 | MAP_DIFFICULTY(m)=calculate_difficulty(m); |
1058 | set_map_reset_time(m); |
1048 | set_map_reset_time(m); |
1059 | INVOKE_MAP (INSTANTIATE, m); |
1049 | m->instantiate (); |
1060 | return (m); |
1050 | return (m); |
1061 | } |
1051 | } |
1062 | |
1052 | |
1063 | /* |
1053 | /* |
1064 | * Loads a map, which has been loaded earlier, from file. |
1054 | * Loads a map, which has been loaded earlier, from file. |
1065 | * Return the map object we load into (this can change from the passed |
1055 | * Return the map object we load into (this can change from the passed |
1066 | * option if we can't find the original map) |
1056 | * option if we can't find the original map) |
1067 | */ |
1057 | */ |
1068 | |
1058 | |
1069 | static mapstruct *load_temporary_map(mapstruct *m) { |
1059 | static mapstruct *load_temporary_map(mapstruct *m) { |
1070 | FILE *fp; |
|
|
1071 | int comp; |
1060 | int comp; |
1072 | char buf[MAX_BUF]; |
1061 | char buf[MAX_BUF]; |
1073 | |
1062 | |
1074 | if (!m->tmpname) { |
1063 | if (!m->tmpname) { |
1075 | LOG(llevError, "No temporary filename for map %s\n", m->path); |
1064 | LOG(llevError, "No temporary filename for map %s\n", m->path); |
… | |
… | |
1079 | if(m==NULL) return NULL; |
1068 | if(m==NULL) return NULL; |
1080 | fix_auto_apply(m); /* Chests which open as default */ |
1069 | fix_auto_apply(m); /* Chests which open as default */ |
1081 | return m; |
1070 | return m; |
1082 | } |
1071 | } |
1083 | |
1072 | |
1084 | if((fp=open_and_uncompress(m->tmpname,0, &comp))==NULL) { |
1073 | object_thawer thawer (m->tmpname); |
1085 | LOG(llevError, "Cannot open %s: %s\n",m->tmpname, strerror_local(errno)); |
1074 | |
|
|
1075 | if (!thawer) |
|
|
1076 | { |
1086 | strcpy(buf, m->path); |
1077 | strcpy (buf, m->path); |
1087 | delete_map(m); |
1078 | delete_map (m); |
1088 | m = load_original_map(buf, 0); |
1079 | m = load_original_map (buf, 0); |
1089 | if(m==NULL) return NULL; |
1080 | if (!m) return NULL; |
1090 | fix_auto_apply(m); /* Chests which open as default */ |
1081 | fix_auto_apply (m); /* Chests which open as default */ |
1091 | return m; |
1082 | return m; |
1092 | } |
1083 | } |
1093 | |
|
|
1094 | object_thawer thawer (fp, m->tmpname); |
|
|
1095 | |
1084 | |
1096 | if (load_map_header(thawer, m)) { |
1085 | if (load_map_header(thawer, m)) { |
1097 | LOG(llevError,"Error loading map header for %s (%s)\n", |
1086 | LOG(llevError,"Error loading map header for %s (%s)\n", |
1098 | m->path, m->tmpname); |
1087 | m->path, m->tmpname); |
1099 | delete_map(m); |
1088 | delete_map(m); |
… | |
… | |
1102 | } |
1091 | } |
1103 | allocate_map(m); |
1092 | allocate_map(m); |
1104 | |
1093 | |
1105 | m->in_memory=MAP_LOADING; |
1094 | m->in_memory=MAP_LOADING; |
1106 | load_objects (m, thawer, 0); |
1095 | load_objects (m, thawer, 0); |
1107 | close_and_delete(fp, comp); |
1096 | |
1108 | m->in_memory=MAP_IN_MEMORY; |
1097 | m->in_memory=MAP_IN_MEMORY; |
1109 | INVOKE_MAP (SWAPIN, m); |
1098 | INVOKE_MAP (SWAPIN, m); |
1110 | return m; |
1099 | return m; |
1111 | } |
1100 | } |
1112 | |
1101 | |
… | |
… | |
1115 | * Return the map object we load into (this can change from the passed |
1104 | * Return the map object we load into (this can change from the passed |
1116 | * option if we can't find the original map) |
1105 | * option if we can't find the original map) |
1117 | */ |
1106 | */ |
1118 | |
1107 | |
1119 | mapstruct *load_overlay_map(const char *filename, mapstruct *m) { |
1108 | mapstruct *load_overlay_map(const char *filename, mapstruct *m) { |
1120 | FILE *fp; |
|
|
1121 | int comp; |
|
|
1122 | char pathname[MAX_BUF]; |
1109 | char pathname[MAX_BUF]; |
1123 | |
1110 | |
1124 | strcpy(pathname, create_overlay_pathname(filename)); |
1111 | strcpy(pathname, create_overlay_pathname(filename)); |
1125 | |
1112 | |
1126 | if((fp=open_and_uncompress(pathname, 0, &comp))==NULL) { |
|
|
1127 | /* LOG(llevDebug,"Can't open overlay %s\n", pathname);*/ |
|
|
1128 | return m; |
|
|
1129 | } |
|
|
1130 | |
|
|
1131 | object_thawer thawer (fp, pathname); |
1113 | object_thawer thawer (pathname); |
|
|
1114 | |
|
|
1115 | if (!thawer) |
|
|
1116 | return m; |
1132 | |
1117 | |
1133 | if (load_map_header(thawer, m)) { |
1118 | if (load_map_header(thawer, m)) { |
1134 | LOG(llevError,"Error loading map header for overlay %s (%s)\n", |
1119 | LOG(llevError,"Error loading map header for overlay %s (%s)\n", |
1135 | m->path, pathname); |
1120 | m->path, pathname); |
1136 | delete_map(m); |
1121 | delete_map(m); |
… | |
… | |
1139 | } |
1124 | } |
1140 | /*allocate_map(m);*/ |
1125 | /*allocate_map(m);*/ |
1141 | |
1126 | |
1142 | m->in_memory=MAP_LOADING; |
1127 | m->in_memory=MAP_LOADING; |
1143 | load_objects (m, thawer, MAP_OVERLAY); |
1128 | load_objects (m, thawer, MAP_OVERLAY); |
1144 | close_and_delete(fp, comp); |
1129 | |
1145 | m->in_memory=MAP_IN_MEMORY; |
1130 | m->in_memory=MAP_IN_MEMORY; |
1146 | return m; |
1131 | return m; |
1147 | } |
1132 | } |
1148 | |
1133 | |
1149 | /****************************************************************************** |
1134 | /****************************************************************************** |
… | |
… | |
1178 | /* |
1163 | /* |
1179 | * Loads unique objects from file(s) into the map which is in memory |
1164 | * Loads unique objects from file(s) into the map which is in memory |
1180 | * m is the map to load unique items into. |
1165 | * m is the map to load unique items into. |
1181 | */ |
1166 | */ |
1182 | static void load_unique_objects(mapstruct *m) { |
1167 | static void load_unique_objects(mapstruct *m) { |
1183 | FILE *fp; |
|
|
1184 | int comp,count; |
1168 | int count; |
1185 | char firstname[MAX_BUF]; |
1169 | char firstname[MAX_BUF]; |
1186 | |
1170 | |
1187 | for (count=0; count<10; count++) { |
1171 | for (count=0; count<10; count++) { |
1188 | sprintf(firstname, "%s.v%02d", create_items_path(m->path), count); |
1172 | sprintf(firstname, "%s.v%02d", create_items_path(m->path), count); |
1189 | if (!access(firstname, R_OK)) break; |
1173 | if (!access(firstname, R_OK)) break; |
1190 | } |
1174 | } |
1191 | /* If we get here, we did not find any map */ |
1175 | /* If we get here, we did not find any map */ |
1192 | if (count==10) return; |
1176 | if (count==10) return; |
1193 | |
1177 | |
1194 | if ((fp=open_and_uncompress(firstname, 0, &comp))==NULL) { |
|
|
1195 | /* There is no expectation that every map will have unique items, but this |
|
|
1196 | * is debug output, so leave it in. |
|
|
1197 | */ |
|
|
1198 | LOG(llevDebug, "Can't open unique items file for %s\n", create_items_path(m->path)); |
|
|
1199 | return; |
|
|
1200 | } |
|
|
1201 | |
|
|
1202 | object_thawer thawer (fp, firstname); |
1178 | object_thawer thawer (firstname); |
|
|
1179 | |
|
|
1180 | if (!thawer) |
|
|
1181 | return; |
1203 | |
1182 | |
1204 | m->in_memory=MAP_LOADING; |
1183 | m->in_memory=MAP_LOADING; |
1205 | if (m->tmpname == NULL) /* if we have loaded unique items from */ |
1184 | if (m->tmpname == NULL) /* if we have loaded unique items from */ |
1206 | delete_unique_items(m); /* original map before, don't duplicate them */ |
1185 | delete_unique_items(m); /* original map before, don't duplicate them */ |
1207 | load_object(thawer, NULL, LO_NOREAD,0); |
|
|
1208 | load_objects (m, thawer, 0); |
1186 | load_objects (m, thawer, 0); |
1209 | close_and_delete(fp, comp); |
1187 | |
1210 | m->in_memory=MAP_IN_MEMORY; |
1188 | m->in_memory=MAP_IN_MEMORY; |
1211 | } |
1189 | } |
1212 | |
1190 | |
1213 | |
1191 | |
1214 | /* |
1192 | /* |
… | |
… | |
1248 | } |
1226 | } |
1249 | else |
1227 | else |
1250 | { |
1228 | { |
1251 | if (!m->tmpname) |
1229 | if (!m->tmpname) |
1252 | m->tmpname = tempnam_local (settings.tmpdir, NULL); |
1230 | m->tmpname = tempnam_local (settings.tmpdir, NULL); |
|
|
1231 | |
1253 | strcpy (filename, m->tmpname); |
1232 | strcpy (filename, m->tmpname); |
1254 | } |
1233 | } |
1255 | |
1234 | |
1256 | LOG (llevDebug, "Saving map %s to %s\n", m->path, filename); |
1235 | LOG (llevDebug, "Saving map %s to %s\n", m->path, filename); |
1257 | m->in_memory = MAP_SAVING; |
1236 | m->in_memory = MAP_SAVING; |
1258 | |
1237 | |
1259 | object_freezer fp (filename); |
1238 | object_freezer freezer; |
1260 | |
1239 | |
1261 | /* legacy */ |
1240 | /* legacy */ |
1262 | fprintf (fp, "arch map\n"); |
1241 | fprintf (freezer, "arch map\n"); |
1263 | if (m->name) |
1242 | if (m->name) |
1264 | fprintf (fp, "name %s\n", m->name); |
1243 | fprintf (freezer, "name %s\n", m->name); |
1265 | if (!flag) |
1244 | if (!flag) |
1266 | fprintf (fp, "swap_time %d\n", m->swap_time); |
1245 | fprintf (freezer, "swap_time %d\n", m->swap_time); |
1267 | if (m->reset_timeout) |
1246 | if (m->reset_timeout) |
1268 | fprintf (fp, "reset_timeout %d\n", m->reset_timeout); |
1247 | fprintf (freezer, "reset_timeout %d\n", m->reset_timeout); |
1269 | if (m->fixed_resettime) |
1248 | if (m->fixed_resettime) |
1270 | fprintf (fp, "fixed_resettime %d\n", m->fixed_resettime); |
1249 | fprintf (freezer, "fixed_resettime %d\n", m->fixed_resettime); |
1271 | /* we unfortunately have no idea if this is a value the creator set |
1250 | /* we unfortunately have no idea if this is a value the creator set |
1272 | * or a difficulty value we generated when the map was first loaded |
1251 | * or a difficulty value we generated when the map was first loaded |
1273 | */ |
1252 | */ |
1274 | if (m->difficulty) |
1253 | if (m->difficulty) |
1275 | fprintf (fp, "difficulty %d\n", m->difficulty); |
1254 | fprintf (freezer, "difficulty %d\n", m->difficulty); |
1276 | if (m->region) |
1255 | if (m->region) |
1277 | fprintf (fp, "region %s\n", m->region->name); |
1256 | fprintf (freezer, "region %s\n", m->region->name); |
1278 | if (m->shopitems) |
1257 | if (m->shopitems) |
1279 | { |
1258 | { |
1280 | print_shop_string (m, shop); |
1259 | print_shop_string (m, shop); |
1281 | fprintf (fp, "shopitems %s\n", shop); |
1260 | fprintf (freezer, "shopitems %s\n", shop); |
1282 | } |
1261 | } |
1283 | if (m->shopgreed) |
1262 | if (m->shopgreed) |
1284 | fprintf (fp, "shopgreed %f\n", m->shopgreed); |
1263 | fprintf (freezer, "shopgreed %f\n", m->shopgreed); |
1285 | #ifndef WIN32 |
1264 | #ifndef WIN32 |
1286 | if (m->shopmin) |
1265 | if (m->shopmin) |
1287 | fprintf (fp, "shopmin %llu\n", m->shopmin); |
1266 | fprintf (freezer, "shopmin %llu\n", m->shopmin); |
1288 | if (m->shopmax) |
1267 | if (m->shopmax) |
1289 | fprintf (fp, "shopmax %llu\n", m->shopmax); |
1268 | fprintf (freezer, "shopmax %llu\n", m->shopmax); |
1290 | #else |
1269 | #else |
1291 | if (m->shopmin) |
1270 | if (m->shopmin) |
1292 | fprintf (fp, "shopmin %I64u\n", m->shopmin); |
1271 | fprintf (freezer, "shopmin %I64u\n", m->shopmin); |
1293 | if (m->shopmax) |
1272 | if (m->shopmax) |
1294 | fprintf (fp, "shopmax %I64u\n", m->shopmax); |
1273 | fprintf (freezer, "shopmax %I64u\n", m->shopmax); |
1295 | #endif |
1274 | #endif |
1296 | if (m->shoprace) |
1275 | if (m->shoprace) |
1297 | fprintf (fp, "shoprace %s\n", m->shoprace); |
1276 | fprintf (freezer, "shoprace %s\n", m->shoprace); |
1298 | if (m->darkness) |
1277 | if (m->darkness) |
1299 | fprintf (fp, "darkness %d\n", m->darkness); |
1278 | fprintf (freezer, "darkness %d\n", m->darkness); |
1300 | if (m->width) |
1279 | if (m->width) |
1301 | fprintf (fp, "width %d\n", m->width); |
1280 | fprintf (freezer, "width %d\n", m->width); |
1302 | if (m->height) |
1281 | if (m->height) |
1303 | fprintf (fp, "height %d\n", m->height); |
1282 | fprintf (freezer, "height %d\n", m->height); |
1304 | if (m->enter_x) |
1283 | if (m->enter_x) |
1305 | fprintf (fp, "enter_x %d\n", m->enter_x); |
1284 | fprintf (freezer, "enter_x %d\n", m->enter_x); |
1306 | if (m->enter_y) |
1285 | if (m->enter_y) |
1307 | fprintf (fp, "enter_y %d\n", m->enter_y); |
1286 | fprintf (freezer, "enter_y %d\n", m->enter_y); |
1308 | if (m->msg) |
1287 | if (m->msg) |
1309 | fprintf (fp, "msg\n%sendmsg\n", m->msg); |
1288 | fprintf (freezer, "msg\n%sendmsg\n", m->msg); |
1310 | if (m->maplore) |
1289 | if (m->maplore) |
1311 | fprintf (fp, "maplore\n%sendmaplore\n", m->maplore); |
1290 | fprintf (freezer, "maplore\n%sendmaplore\n", m->maplore); |
1312 | if (m->unique) |
1291 | if (m->unique) |
1313 | fprintf (fp, "unique %d\n", m->unique); |
1292 | fprintf (freezer, "unique %d\n", m->unique); |
1314 | if (m->templatemap) |
1293 | if (m->templatemap) |
1315 | fprintf (fp, "template %d\n", m->templatemap); |
1294 | fprintf (freezer, "template %d\n", m->templatemap); |
1316 | if (m->outdoor) |
1295 | if (m->outdoor) |
1317 | fprintf (fp, "outdoor %d\n", m->outdoor); |
1296 | fprintf (freezer, "outdoor %d\n", m->outdoor); |
1318 | if (m->temp) |
1297 | if (m->temp) |
1319 | fprintf (fp, "temp %d\n", m->temp); |
1298 | fprintf (freezer, "temp %d\n", m->temp); |
1320 | if (m->pressure) |
1299 | if (m->pressure) |
1321 | fprintf (fp, "pressure %d\n", m->pressure); |
1300 | fprintf (freezer, "pressure %d\n", m->pressure); |
1322 | if (m->humid) |
1301 | if (m->humid) |
1323 | fprintf (fp, "humid %d\n", m->humid); |
1302 | fprintf (freezer, "humid %d\n", m->humid); |
1324 | if (m->windspeed) |
1303 | if (m->windspeed) |
1325 | fprintf (fp, "windspeed %d\n", m->windspeed); |
1304 | fprintf (freezer, "windspeed %d\n", m->windspeed); |
1326 | if (m->winddir) |
1305 | if (m->winddir) |
1327 | fprintf (fp, "winddir %d\n", m->winddir); |
1306 | fprintf (freezer, "winddir %d\n", m->winddir); |
1328 | if (m->sky) |
1307 | if (m->sky) |
1329 | fprintf (fp, "sky %d\n", m->sky); |
1308 | fprintf (freezer, "sky %d\n", m->sky); |
1330 | if (m->nosmooth) |
1309 | if (m->nosmooth) |
1331 | fprintf (fp, "nosmooth %d\n", m->nosmooth); |
1310 | fprintf (freezer, "nosmooth %d\n", m->nosmooth); |
1332 | if (m->safe_map) |
|
|
1333 | fprintf (fp, "safe_map %d\n", m->safe_map); |
|
|
1334 | |
1311 | |
1335 | /* Save any tiling information, except on overlays */ |
1312 | /* Save any tiling information, except on overlays */ |
1336 | if (flag != 2) |
1313 | if (flag != 2) |
1337 | for (i = 0; i < 4; i++) |
1314 | for (i = 0; i < 4; i++) |
1338 | if (m->tile_path[i]) |
1315 | if (m->tile_path[i]) |
1339 | fprintf (fp, "tile_path_%d %s\n", i + 1, m->tile_path[i]); |
1316 | fprintf (freezer, "tile_path_%d %s\n", i + 1, m->tile_path[i]); |
1340 | |
1317 | |
|
|
1318 | freezer.put (m); |
1341 | fprintf (fp, "end\n"); |
1319 | fprintf (freezer, "end\n"); |
1342 | |
1320 | |
1343 | /* In the game save unique items in the different file, but |
1321 | /* In the game save unique items in the different file, but |
1344 | * in the editor save them to the normal map file. |
1322 | * in the editor save them to the normal map file. |
1345 | * If unique map, save files in the proper destination (set by |
1323 | * If unique map, save files in the proper destination (set by |
1346 | * player) |
1324 | * player) |
1347 | */ |
1325 | */ |
1348 | if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) |
1326 | if ((flag == 0 || flag == 2) && !m->unique && !m->templatemap) |
1349 | { |
1327 | { |
|
|
1328 | object_freezer unique; |
|
|
1329 | |
|
|
1330 | if (flag == 2) |
|
|
1331 | save_objects (m, freezer, unique, 2); |
|
|
1332 | else |
|
|
1333 | save_objects (m, freezer, unique, 0); |
|
|
1334 | |
1350 | sprintf (buf, "%s.v00", create_items_path (m->path)); |
1335 | sprintf (buf, "%s.v00", create_items_path (m->path)); |
1351 | |
1336 | |
1352 | object_freezer fp2 (buf); |
1337 | unique.save (buf); |
1353 | |
|
|
1354 | if (flag == 2) |
|
|
1355 | save_objects (m, fp, fp2, 2); |
|
|
1356 | else |
|
|
1357 | save_objects (m, fp, fp2, 0); |
|
|
1358 | } |
1338 | } |
1359 | else |
1339 | else |
1360 | { /* save same file when not playing, like in editor */ |
1340 | { /* save same file when not playing, like in editor */ |
1361 | save_objects (m, fp, fp, 0); |
1341 | save_objects (m, freezer, freezer, 0); |
1362 | } |
1342 | } |
|
|
1343 | |
|
|
1344 | freezer.save (filename); |
1363 | |
1345 | |
1364 | return 0; |
1346 | return 0; |
1365 | } |
1347 | } |
1366 | |
1348 | |
1367 | |
1349 | |
… | |
… | |
1412 | clean_object(op); |
1394 | clean_object(op); |
1413 | remove_ob(op); |
1395 | remove_ob(op); |
1414 | free_object(op); |
1396 | free_object(op); |
1415 | } |
1397 | } |
1416 | } |
1398 | } |
1417 | #ifdef MANY_CORES |
|
|
1418 | /* I see periodic cores on metalforge where a map has been swapped out, but apparantly |
|
|
1419 | * an item on that map was not saved - look for that condition and die as appropriate - |
|
|
1420 | * this leaves more of the map data intact for better debugging. |
|
|
1421 | */ |
|
|
1422 | for (op=objects; op!=NULL; op=op->next) { |
|
|
1423 | if (!QUERY_FLAG(op, FLAG_REMOVED) && op->map == m) { |
|
|
1424 | LOG(llevDebug,"free_all_objects: object %s still on map after it should have been freed\n", op->name); |
|
|
1425 | abort(); |
|
|
1426 | } |
|
|
1427 | } |
|
|
1428 | #endif |
|
|
1429 | } |
1399 | } |
1430 | |
1400 | |
1431 | /* |
1401 | /* |
1432 | * Frees everything allocated by the given mapstructure. |
1402 | * Frees everything allocated by the given mapstructure. |
1433 | * don't free tmpname - our caller is left to do that |
1403 | * don't free tmpname - our caller is left to do that |
… | |
… | |
1513 | m->path); |
1483 | m->path); |
1514 | } |
1484 | } |
1515 | else |
1485 | else |
1516 | last->next = m->next; |
1486 | last->next = m->next; |
1517 | |
1487 | |
1518 | free (m); |
1488 | delete m; |
1519 | } |
1489 | } |
1520 | |
1490 | |
1521 | |
1491 | |
1522 | |
1492 | |
1523 | /* |
1493 | /* |
… | |
… | |
1566 | if (flags & MAP_PLAYER_UNIQUE) |
1536 | if (flags & MAP_PLAYER_UNIQUE) |
1567 | LOG(llevDebug, "Trying to load map %s.\n", name); |
1537 | LOG(llevDebug, "Trying to load map %s.\n", name); |
1568 | else |
1538 | else |
1569 | LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); |
1539 | LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); |
1570 | |
1540 | |
|
|
1541 | //0.427459955215454 /var/crossfire/players/Saladon/_scorn_apartment_apartments |
|
|
1542 | //0.414906024932861 |
|
|
1543 | //0.427063941955566 |
|
|
1544 | eval_pv ("$x = Event::time", 1);//D |
1571 | if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) |
1545 | if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) |
1572 | return (NULL); |
1546 | return (NULL); |
|
|
1547 | eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D |
1573 | |
1548 | |
1574 | fix_auto_apply(m); /* Chests which open as default */ |
1549 | fix_auto_apply(m); /* Chests which open as default */ |
1575 | |
1550 | |
1576 | /* If a player unique map, no extra unique object file to load. |
1551 | /* If a player unique map, no extra unique object file to load. |
1577 | * if from the editor, likewise. |
1552 | * if from the editor, likewise. |
1578 | */ |
1553 | */ |
1579 | if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) |
1554 | if (!(flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) |
1580 | load_unique_objects(m); |
1555 | load_unique_objects(m); |
1581 | |
1556 | |
1582 | if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { |
1557 | if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { |
1583 | m=load_overlay_map(name, m); |
1558 | m=load_overlay_map(name, m); |
1584 | if (m==NULL) |
1559 | if (m==NULL) |
1585 | return NULL; |
1560 | return NULL; |
1586 | } |
1561 | } |
|
|
1562 | |
|
|
1563 | if (flags & MAP_PLAYER_UNIQUE) |
|
|
1564 | INVOKE_MAP (SWAPIN, m); |
1587 | |
1565 | |
1588 | } else { |
1566 | } else { |
1589 | /* If in this loop, we found a temporary map, so load it up. */ |
1567 | /* If in this loop, we found a temporary map, so load it up. */ |
1590 | |
1568 | |
1591 | m=load_temporary_map (m); |
1569 | m=load_temporary_map (m); |