1 | /* |
1 | /* |
2 | * static char *rcsid_map_c = |
2 | * static char *rcsid_map_c = |
3 | * "$Id: map.C,v 1.20 2006/09/03 00:18:40 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 | |
… | |
… | |
494 | 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); |
495 | } /* for at = tmp->arch->more */ |
495 | } /* for at = tmp->arch->more */ |
496 | } /* for objects on this space */ |
496 | } /* for objects on this space */ |
497 | } |
497 | } |
498 | |
498 | |
499 | |
|
|
500 | |
|
|
501 | /* |
499 | /* |
502 | * 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 |
503 | * file pointer. |
501 | * file pointer. |
504 | * mapflags is the same as we get with load_original_map |
502 | * mapflags is the same as we get with load_original_map |
505 | */ |
503 | */ |
506 | |
504 | void |
507 | void load_objects (mapstruct *m, object_thawer &fp, int mapflags) { |
505 | load_objects (mapstruct *m, object_thawer &fp, int mapflags) |
508 | int i,j,bufstate=LO_NEWFILE; |
506 | { |
|
|
507 | int i, j; |
509 | int unique; |
508 | int unique; |
510 | object *op, *prev=NULL,*last_more=NULL, *otmp; |
509 | object *op, *prev = NULL, *last_more = NULL, *otmp; |
511 | |
510 | |
512 | op=get_object(); |
511 | op = get_object (); |
513 | op->map = m; /* To handle buttons correctly */ |
512 | op->map = m; /* To handle buttons correctly */ |
514 | |
513 | |
515 | while((i = load_object (fp, op, bufstate, mapflags))) { |
514 | while ((i = load_object (fp, op, mapflags))) |
516 | /* Since the loading of the map header does not load an object |
515 | { |
517 | * anymore, we need to pass LO_NEWFILE for the first object loaded, |
|
|
518 | * and then switch to LO_REPEAT for faster loading. |
|
|
519 | */ |
|
|
520 | bufstate = LO_REPEAT; |
|
|
521 | |
|
|
522 | /* if the archetype for the object is null, means that we |
516 | /* if the archetype for the object is null, means that we |
523 | * 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 |
524 | * 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. |
525 | */ |
519 | */ |
526 | if (op->arch==NULL) { |
520 | if (op->arch == NULL) |
527 | LOG(llevDebug,"Discarding object without arch: %s\n", op->name?(const char *)op->name:"(null)"); |
521 | { |
|
|
522 | LOG (llevDebug, "Discarding object without arch: %s\n", |
|
|
523 | op->name ? (const char *) op->name : "(null)"); |
528 | continue; |
524 | continue; |
|
|
525 | } |
|
|
526 | |
|
|
527 | |
|
|
528 | switch (i) |
529 | } |
529 | { |
530 | |
|
|
531 | |
|
|
532 | switch(i) { |
|
|
533 | case LL_NORMAL: |
530 | case LL_NORMAL: |
534 | /* 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 */ |
535 | if ((QUERY_FLAG(op, FLAG_IS_FLOOR) || |
532 | if ((QUERY_FLAG (op, FLAG_IS_FLOOR) || |
536 | QUERY_FLAG(op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) |
533 | QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) |
537 | 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); |
538 | else |
537 | else |
539 | 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); |
540 | |
541 | |
541 | if (op->inv) |
542 | if (op->inv) |
542 | sum_weight(op); |
543 | sum_weight (op); |
543 | |
544 | |
544 | prev=op,last_more=op; |
545 | prev = op, last_more = op; |
545 | break; |
546 | break; |
546 | |
547 | |
547 | case LL_MORE: |
548 | case LL_MORE: |
548 | 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); |
549 | op->head=prev,last_more->more=op,last_more=op; |
552 | op->head = prev, last_more->more = op, last_more = op; |
550 | break; |
553 | break; |
551 | } |
554 | } |
|
|
555 | |
552 | if (mapflags & MAP_STYLE) { |
556 | if (mapflags & MAP_STYLE) |
553 | remove_from_active_list(op); |
557 | remove_from_active_list (op); |
554 | } |
558 | |
555 | op=get_object(); |
559 | op = get_object (); |
556 | op->map = m; |
560 | op->map = m; |
557 | } |
561 | } |
|
|
562 | |
558 | for (i=0;i<m->width;i++){ |
563 | for (i = 0; i < m->width; i++) |
|
|
564 | { |
559 | for (j=0;j<m->height;j++){ |
565 | for (j = 0; j < m->height; j++) |
|
|
566 | { |
560 | unique =0; |
567 | unique = 0; |
561 | /* check for unique items, or unique squares */ |
568 | /* check for unique items, or unique squares */ |
562 | 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) |
563 | 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)) |
564 | unique = 1; |
573 | unique = 1; |
565 | if (!(mapflags & (MAP_OVERLAY|MAP_PLAYER_UNIQUE) || unique)) |
574 | if (!(mapflags & (MAP_OVERLAY | MAP_PLAYER_UNIQUE) || unique)) |
566 | SET_FLAG(otmp, FLAG_OBJ_ORIGINAL); |
575 | SET_FLAG (otmp, FLAG_OBJ_ORIGINAL); |
567 | } |
576 | } |
568 | } |
577 | } |
569 | } |
578 | } |
|
|
579 | |
570 | free_object(op); |
580 | free_object (op); |
571 | link_multipart_objects(m); |
581 | link_multipart_objects (m); |
572 | } |
582 | } |
573 | |
583 | |
574 | /* 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. |
575 | * 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, |
576 | * 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 |
… | |
… | |
806 | value = NULL; |
816 | value = NULL; |
807 | break; |
817 | break; |
808 | } |
818 | } |
809 | } |
819 | } |
810 | } |
820 | } |
|
|
821 | |
811 | if (!end) { |
822 | if (!end) { |
812 | 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", |
813 | buf); |
824 | buf); |
814 | return 1; |
825 | return 1; |
815 | } |
826 | } |
816 | |
|
|
817 | |
827 | |
818 | /* 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 |
819 | * to. We've already done the work to null terminate key, |
829 | * to. We've already done the work to null terminate key, |
820 | * and strip off any leading spaces for both of these. |
830 | * and strip off any leading spaces for both of these. |
821 | * 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 - |
… | |
… | |
1001 | |
1011 | |
1002 | mapstruct *load_original_map(const char *filename, int flags) { |
1012 | mapstruct *load_original_map(const char *filename, int flags) { |
1003 | mapstruct *m; |
1013 | mapstruct *m; |
1004 | char pathname[MAX_BUF]; |
1014 | char pathname[MAX_BUF]; |
1005 | |
1015 | |
1006 | LOG(llevDebug, "load_original_map: %s (%x)\n", filename,flags); |
|
|
1007 | if (flags & MAP_PLAYER_UNIQUE) |
1016 | if (flags & MAP_PLAYER_UNIQUE) |
1008 | strcpy(pathname, filename); |
1017 | strcpy(pathname, filename); |
1009 | else if (flags & MAP_OVERLAY) |
1018 | else if (flags & MAP_OVERLAY) |
1010 | strcpy(pathname, create_overlay_pathname(filename)); |
1019 | strcpy(pathname, create_overlay_pathname(filename)); |
1011 | else |
1020 | else |
1012 | strcpy(pathname, create_pathname(filename)); |
1021 | strcpy(pathname, create_pathname(filename)); |
|
|
1022 | |
|
|
1023 | LOG(llevDebug, "load_original_map(%x): %s (%s)\n", flags, filename, pathname); |
1013 | |
1024 | |
1014 | object_thawer thawer (pathname); |
1025 | object_thawer thawer (pathname); |
1015 | |
1026 | |
1016 | if (!thawer) |
1027 | if (!thawer) |
1017 | return 0; |
1028 | return 0; |
… | |
… | |
1170 | return; |
1181 | return; |
1171 | |
1182 | |
1172 | m->in_memory=MAP_LOADING; |
1183 | m->in_memory=MAP_LOADING; |
1173 | if (m->tmpname == NULL) /* if we have loaded unique items from */ |
1184 | if (m->tmpname == NULL) /* if we have loaded unique items from */ |
1174 | delete_unique_items(m); /* original map before, don't duplicate them */ |
1185 | delete_unique_items(m); /* original map before, don't duplicate them */ |
1175 | load_object(thawer, NULL, LO_NOREAD,0); |
|
|
1176 | load_objects (m, thawer, 0); |
1186 | load_objects (m, thawer, 0); |
1177 | |
1187 | |
1178 | m->in_memory=MAP_IN_MEMORY; |
1188 | m->in_memory=MAP_IN_MEMORY; |
1179 | } |
1189 | } |
1180 | |
1190 | |
… | |
… | |
1526 | if (flags & MAP_PLAYER_UNIQUE) |
1536 | if (flags & MAP_PLAYER_UNIQUE) |
1527 | LOG(llevDebug, "Trying to load map %s.\n", name); |
1537 | LOG(llevDebug, "Trying to load map %s.\n", name); |
1528 | else |
1538 | else |
1529 | LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); |
1539 | LOG(llevDebug, "Trying to load map %s.\n", create_pathname(name)); |
1530 | |
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 |
1531 | if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) |
1545 | if (!(m = load_original_map(name, (flags & MAP_PLAYER_UNIQUE)))) |
1532 | return (NULL); |
1546 | return (NULL); |
|
|
1547 | eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D |
1533 | |
1548 | |
1534 | fix_auto_apply(m); /* Chests which open as default */ |
1549 | fix_auto_apply(m); /* Chests which open as default */ |
1535 | |
1550 | |
1536 | /* 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. |
1537 | * if from the editor, likewise. |
1552 | * if from the editor, likewise. |
1538 | */ |
1553 | */ |
1539 | if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) |
1554 | if (!(flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE))) |
1540 | load_unique_objects(m); |
1555 | load_unique_objects(m); |
1541 | |
1556 | |
1542 | if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { |
1557 | if (! (flags & (MAP_FLUSH|MAP_PLAYER_UNIQUE|MAP_OVERLAY))) { |
1543 | m=load_overlay_map(name, m); |
1558 | m=load_overlay_map(name, m); |
1544 | if (m==NULL) |
1559 | if (m==NULL) |