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.52 by root, Tue Dec 26 20:04:09 2006 UTC vs.
Revision 1.55 by root, Wed Dec 27 18:09:48 2006 UTC

19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 The authors can be reached via e-mail at <crossfire@schmorp.de> 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
22*/ 22*/
23 23
24
25#include <global.h> 24#include <global.h>
26#include <funcpoint.h> 25#include <funcpoint.h>
27 26
28#include <loader.h> 27#include <loader.h>
29#include <unistd.h> 28#include <unistd.h>
35 * return NULL if no match is found. 34 * return NULL if no match is found.
36 */ 35 */
37maptile * 36maptile *
38has_been_loaded (const char *name) 37has_been_loaded (const char *name)
39{ 38{
40 maptile *map;
41
42 if (!name || !*name) 39 if (!name || !*name)
43 return 0; 40 return 0;
44 41
45 for (map = first_map; map; map = map->next) 42 for_all_maps (map)
46 if (!strcmp (name, map->path)) 43 if (!strcmp (name, map->path))
47 break;
48
49 return (map); 44 return map;
45
46 return 0;
50} 47}
51 48
52/* 49/*
53 * This makes a path absolute outside the world of Crossfire. 50 * This makes a path absolute outside the world of Crossfire.
54 * In other words, it prepends LIBDIR/MAPDIR/ to the given path 51 * In other words, it prepends LIBDIR/MAPDIR/ to the given path
221 */ 218 */
222 219
223void 220void
224dump_all_maps (void) 221dump_all_maps (void)
225{ 222{
226 maptile *m; 223 for_all_maps (m)
227
228 for (m = first_map; m; m = m->next)
229 dump_map (m); 224 dump_map (m);
230} 225}
231 226
232/* This rolls up wall, blocks_magic, blocks_view, etc, all into 227/* This rolls up wall, blocks_magic, blocks_view, etc, all into
233 * one function that just returns a P_.. value (see map.h) 228 * one function that just returns a P_.. value (see map.h)
476 * for objects whose arch says they are multipart yet according to the 471 * for objects whose arch says they are multipart yet according to the
477 * info we have, they only have the head (as would be expected when 472 * info we have, they only have the head (as would be expected when
478 * they are saved). We do have to look for the old maps that did save 473 * they are saved). We do have to look for the old maps that did save
479 * the more sections and not re-add sections for them. 474 * the more sections and not re-add sections for them.
480 */ 475 */
481
482static void 476static void
483link_multipart_objects (maptile *m) 477link_multipart_objects (maptile *m)
484{ 478{
485 int x, y; 479 int x, y;
486 object *tmp, *op, *last, *above; 480 object *tmp, *op, *last, *above;
617 for (op = m->at (i, j).bot; op; op = op->above) 611 for (op = m->at (i, j).bot; op; op = op->above)
618 { 612 {
619 if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR]) 613 if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR])
620 unique = 1; 614 unique = 1;
621 615
622 if (op->type == PLAYER) 616 if (!op->can_map_save ())
623 continue;
624
625 if (op->head || op->owner)
626 continue; 617 continue;
627 618
628 if (unique || op->flag [FLAG_UNIQUE]) 619 if (unique || op->flag [FLAG_UNIQUE])
629 save_object (fp2, op, 1); 620 save_object (fp2, op, 1);
630 else if (flag == 0 || (flag == 2 && (!op->flag [FLAG_OBJ_ORIGINAL] && !op->flag [FLAG_UNPAID]))) 621 else if (flag == 0 || (flag == 2 && (!op->flag [FLAG_OBJ_ORIGINAL] && !op->flag [FLAG_UNPAID])))
634} 625}
635 626
636maptile::maptile () 627maptile::maptile ()
637{ 628{
638 in_memory = MAP_SWAPPED; 629 in_memory = MAP_SWAPPED;
630
639 /* The maps used to pick up default x and y values from the 631 /* The maps used to pick up default x and y values from the
640 * map archetype. Mimic that behaviour. 632 * map archetype. Mimic that behaviour.
641 */ 633 */
642 this->width = 16; 634 width = 16;
643 this->height = 16; 635 height = 16;
644 this->reset_timeout = 0; 636 reset_timeout = 0;
645 this->timeout = 300; 637 timeout = 300;
646 this->enter_x = 0; 638 enter_x = 0;
647 this->enter_y = 0; 639 enter_y = 0;
648 /*set part to -1 indicating conversion to weather map not yet done */ 640 /*set part to -1 indicating conversion to weather map not yet done */
649 this->worldpartx = -1; 641 worldpartx = -1;
650 this->worldparty = -1; 642 worldparty = -1;
643}
644
645void
646maptile::link ()
647{
648 next = first_map;
649 first_map = this;
650}
651
652void
653maptile::unlink ()
654{
655 if (first_map == this)
656 first_map = next;
657 else
658 {
659 for_all_maps (m)
660 if (m->next = this)
661 {
662 m->next = next;
663 return;
664 }
665
666 LOG (llevError, "maptile::unlink() map not on list: %s\n", path);
667 }
651} 668}
652 669
653/* 670/*
654 * Allocates, initialises, and returns a pointer to a maptile. 671 * Allocates, initialises, and returns a pointer to a maptile.
655 * Modified to no longer take a path option which was not being 672 * Modified to no longer take a path option which was not being
656 * used anyways. MSW 2001-07-01 673 * used anyways. MSW 2001-07-01
657 */ 674 */
658maptile * 675maptile *
659get_linked_map (void) 676get_linked_map (void)
660{ 677{
661 maptile *mp, *map = new maptile; 678 maptile *map = new maptile;
662 679 map->link ();
663 for (mp = first_map; mp && mp->next; mp = mp->next);
664
665 if (mp == NULL)
666 first_map = map;
667 else
668 mp->next = map;
669
670 return map; 680 return map;
671} 681}
672 682
673/* 683/*
674 * Allocates the arrays contained in a maptile. 684 * Allocates the arrays contained in a maptile.
685 * that is their poor assumption. 695 * that is their poor assumption.
686 */ 696 */
687 if (spaces) 697 if (spaces)
688 { 698 {
689 LOG (llevError, "allocate_map called with already allocated map (%s)\n", path); 699 LOG (llevError, "allocate_map called with already allocated map (%s)\n", path);
690 free (spaces); 700 sfree (spaces, size ());
691 } 701 }
692 702
693 spaces = (mapspace *) 703 spaces = salloc0<mapspace> (size ());
694 calloc (1, width * height * sizeof (mapspace));
695
696 if (!spaces)
697 fatal (OUT_OF_MEMORY);
698} 704}
699 705
700/* Create and returns a map of the specific size. Used 706/* Create and returns a map of the specific size. Used
701 * in random map code and the editor. 707 * in random map code and the editor.
702 */ 708 */
703maptile * 709maptile *
704get_empty_map (int sizex, int sizey) 710get_empty_map (int sizex, int sizey)
705{ 711{
706 maptile *m = get_linked_map (); 712 maptile *m = get_linked_map ();
707 713
708 m->width = sizex; 714 m->width = sizex;
709 m->height = sizey; 715 m->height = sizey;
710 m->in_memory = MAP_SWAPPED; 716 m->in_memory = MAP_SWAPPED;
717
711 m->allocate (); 718 m->allocate ();
712 719
713 return m; 720 return m;
714} 721}
715 722
716/* Takes a string from a map definition and outputs a pointer to the array of shopitems 723/* Takes a string from a map definition and outputs a pointer to the array of shopitems
717 * corresponding to that string. Memory is allocated for this, it must be freed 724 * corresponding to that string. Memory is allocated for this, it must be freed
718 * at a later date. 725 * at a later date.
719 * Called by parse_map_headers below. 726 * Called by parse_map_headers below.
720 */ 727 */
721
722static shopitems * 728static shopitems *
723parse_shop_string (const char *input_string) 729parse_shop_string (const char *input_string)
724{ 730{
725 char *shop_string, *p, *q, *next_semicolon, *next_colon; 731 char *shop_string, *p, *q, *next_semicolon, *next_colon;
726 shopitems *items = NULL; 732 shopitems *items = NULL;
735 p = strchr (p, ';'); 741 p = strchr (p, ';');
736 number_of_entries++; 742 number_of_entries++;
737 if (p) 743 if (p)
738 p++; 744 p++;
739 } 745 }
746
740 p = shop_string; 747 p = shop_string;
741 strip_endline (p); 748 strip_endline (p);
742 items = new shopitems[number_of_entries + 1]; 749 items = new shopitems[number_of_entries + 1];
743 for (i = 0; i < number_of_entries; i++) 750 for (i = 0; i < number_of_entries; i++)
744 { 751 {
745 if (!p) 752 if (!p)
746 { 753 {
747 LOG (llevError, "parse_shop_string: I seem to have run out of string, that shouldn't happen.\n"); 754 LOG (llevError, "parse_shop_string: I seem to have run out of string, that shouldn't happen.\n");
748 break; 755 break;
749 } 756 }
757
750 next_semicolon = strchr (p, ';'); 758 next_semicolon = strchr (p, ';');
751 next_colon = strchr (p, ':'); 759 next_colon = strchr (p, ':');
752 /* if there is a stregth specified, figure out what it is, we'll need it soon. */ 760 /* if there is a stregth specified, figure out what it is, we'll need it soon. */
753 if (next_colon && (!next_semicolon || next_colon < next_semicolon)) 761 if (next_colon && (!next_semicolon || next_colon < next_semicolon))
754 items[i].strength = atoi (strchr (p, ':') + 1); 762 items[i].strength = atoi (strchr (p, ':') + 1);
781 * the next entry while we're at it, better print a warning 789 * the next entry while we're at it, better print a warning
782 */ 790 */
783 LOG (llevError, "invalid type %s defined in shopitems in string %s\n", p, input_string); 791 LOG (llevError, "invalid type %s defined in shopitems in string %s\n", p, input_string);
784 } 792 }
785 } 793 }
794
786 items[i].index = number_of_entries; 795 items[i].index = number_of_entries;
787 if (next_semicolon) 796 if (next_semicolon)
788 p = ++next_semicolon; 797 p = ++next_semicolon;
789 else 798 else
790 p = NULL; 799 p = NULL;
791 } 800 }
801
792 free (shop_string); 802 free (shop_string);
793 return items; 803 return items;
794} 804}
795 805
796/* opposite of parse string, this puts the string that was originally fed in to 806/* opposite of parse string, this puts the string that was originally fed in to
805 for (i = 0; i < m->shopitems[0].index; i++) 815 for (i = 0; i < m->shopitems[0].index; i++)
806 { 816 {
807 if (m->shopitems[i].typenum) 817 if (m->shopitems[i].typenum)
808 { 818 {
809 if (m->shopitems[i].strength) 819 if (m->shopitems[i].strength)
810 {
811 sprintf (tmp, "%s:%d;", m->shopitems[i].name, m->shopitems[i].strength); 820 sprintf (tmp, "%s:%d;", m->shopitems[i].name, m->shopitems[i].strength);
812 }
813 else 821 else
814 sprintf (tmp, "%s;", m->shopitems[i].name); 822 sprintf (tmp, "%s;", m->shopitems[i].name);
815 } 823 }
816 else 824 else
817 { 825 {
818 if (m->shopitems[i].strength) 826 if (m->shopitems[i].strength)
819 {
820 sprintf (tmp, "*:%d;", m->shopitems[i].strength); 827 sprintf (tmp, "*:%d;", m->shopitems[i].strength);
821 }
822 else 828 else
823 sprintf (tmp, "*"); 829 sprintf (tmp, "*");
824 } 830 }
831
825 strcat (output_string, tmp); 832 strcat (output_string, tmp);
826 } 833 }
827} 834}
828 835
829/* This loads the header information of the map. The header 836/* This loads the header information of the map. The header
1097 * MAP_BLOCK, in which case we block on this load. This happens in all 1104 * MAP_BLOCK, in which case we block on this load. This happens in all
1098 * cases, no matter if this flag is set or not. 1105 * cases, no matter if this flag is set or not.
1099 * MAP_STYLE: style map - don't add active objects, don't add to server 1106 * MAP_STYLE: style map - don't add active objects, don't add to server
1100 * managed map list. 1107 * managed map list.
1101 */ 1108 */
1102
1103maptile * 1109maptile *
1104load_original_map (const char *filename, int flags) 1110load_original_map (const char *filename, int flags)
1105{ 1111{
1106 maptile *m; 1112 maptile *m;
1107 char pathname[MAX_BUF]; 1113 char pathname[MAX_BUF];
1146/* 1152/*
1147 * Loads a map, which has been loaded earlier, from file. 1153 * Loads a map, which has been loaded earlier, from file.
1148 * Return the map object we load into (this can change from the passed 1154 * Return the map object we load into (this can change from the passed
1149 * option if we can't find the original map) 1155 * option if we can't find the original map)
1150 */ 1156 */
1151
1152static maptile * 1157static maptile *
1153load_temporary_map (maptile *m) 1158load_temporary_map (maptile *m)
1154{ 1159{
1155 char buf[MAX_BUF]; 1160 char buf[MAX_BUF];
1156 1161
1200/* 1205/*
1201 * Loads a map, which has been loaded earlier, from file. 1206 * Loads a map, which has been loaded earlier, from file.
1202 * Return the map object we load into (this can change from the passed 1207 * Return the map object we load into (this can change from the passed
1203 * option if we can't find the original map) 1208 * option if we can't find the original map)
1204 */ 1209 */
1205
1206maptile * 1210maptile *
1207load_overlay_map (const char *filename, maptile *m) 1211load_overlay_map (const char *filename, maptile *m)
1208{ 1212{
1209 char pathname[MAX_BUF]; 1213 char pathname[MAX_BUF];
1210 1214
1260 op->destroy (); 1264 op->destroy ();
1261 } 1265 }
1262 } 1266 }
1263 } 1267 }
1264} 1268}
1265
1266 1269
1267/* 1270/*
1268 * Loads unique objects from file(s) into the map which is in memory 1271 * Loads unique objects from file(s) into the map which is in memory
1269 * m is the map to load unique items into. 1272 * m is the map to load unique items into.
1270 */ 1273 */
1487 // TODO: use new/delete 1490 // TODO: use new/delete
1488 1491
1489 if (flag && m->spaces) 1492 if (flag && m->spaces)
1490 free_all_objects (m); 1493 free_all_objects (m);
1491 1494
1495 sfree (m->spaces, m->size ()), m->spaces = 0;
1496
1492 free (m->name), m->name = 0; 1497 free (m->name), m->name = 0;
1493 free (m->spaces), m->spaces = 0;
1494 free (m->msg), m->msg = 0; 1498 free (m->msg), m->msg = 0;
1495 free (m->maplore), m->maplore = 0; 1499 free (m->maplore), m->maplore = 0;
1496 free (m->shoprace), m->shoprace = 0; 1500 free (m->shoprace), m->shoprace = 0;
1497 delete [] m->shopitems, m->shopitems = 0; 1501 delete [] m->shopitems, m->shopitems = 0;
1498 1502
1499 if (m->buttons) 1503 if (m->buttons)
1500 free_objectlinkpt (m->buttons), m->buttons = 0; 1504 free_objectlinkpt (m->buttons), m->buttons = 0;
1501 1505
1502 for (int i = 0; i < 4; i++) 1506 for (int i = 0; i < 4; i++)
1503 {
1504 if (m->tile_path[i])
1505 free (m->tile_path[i]), m->tile_path[i] = 0; 1507 free (m->tile_path[i]), m->tile_path[i] = 0;
1506
1507 m->tile_map[i] = 0;
1508 }
1509 1508
1510 m->in_memory = MAP_SWAPPED; 1509 m->in_memory = MAP_SWAPPED;
1511} 1510}
1512 1511
1513maptile::~maptile () 1512maptile::~maptile ()
1514{ 1513{
1515 free_map (this, 1); 1514 assert (destroyed ());
1516 free (tmpname);
1517} 1515}
1518 1516
1519void 1517void
1520maptile::do_destroy () 1518maptile::do_destroy ()
1521{ 1519{
1522 attachable::do_destroy (); 1520 attachable::do_destroy ();
1523 1521
1524 free_all_objects (this); 1522 unlink ();
1523
1524 free_map (this, 1);
1525 free (tmpname), tmpname = 0;
1525 1526
1526 /* We need to look through all the maps and see if any maps 1527 /* We need to look through all the maps and see if any maps
1527 * are pointing at this one for tiling information. Since 1528 * are pointing at this one for tiling information. Since
1528 * tiling can be asymetric, we just can not look to see which 1529 * tiling can be asymetric, we just can not look to see which
1529 * maps this map tiles with and clears those. 1530 * maps this map tiles with and clears those.
1530 */ 1531 */
1531 //TODO: non-euclidean-tiling MUST GO 1532 //TODO: non-euclidean-tiling MUST GO
1532 for (maptile *m = first_map; m; m = m->next) 1533 for_all_maps (m)
1533 for (int i = 0; i < 4; i++) 1534 for (int i = 0; i < 4; i++)
1534 if (m->tile_map[i] == this) 1535 if (m->tile_map[i] == this)
1535 m->tile_map[i] = 0; 1536 m->tile_map[i] = 0;
1536
1537 if (first_map == this)
1538 first_map = next;
1539 else
1540 for (maptile *m = first_map; m; m = m->next)
1541 if (m->next = this)
1542 {
1543 m->next = next;
1544 break;
1545 }
1546} 1537}
1547 1538
1548//TODO: must go 1539//TODO: must go
1549void 1540void
1550delete_map (maptile *m) 1541delete_map (maptile *m)
1598 if (flags & MAP_PLAYER_UNIQUE) 1589 if (flags & MAP_PLAYER_UNIQUE)
1599 LOG (llevDebug, "Trying to load map %s.\n", name); 1590 LOG (llevDebug, "Trying to load map %s.\n", name);
1600 else 1591 else
1601 LOG (llevDebug, "Trying to load map %s.\n", create_pathname (name)); 1592 LOG (llevDebug, "Trying to load map %s.\n", create_pathname (name));
1602 1593
1603 //eval_pv ("$x = Event::time", 1);//D
1604 if (!(m = load_original_map (name, (flags & MAP_PLAYER_UNIQUE)))) 1594 if (!(m = load_original_map (name, (flags & MAP_PLAYER_UNIQUE))))
1605 return (NULL); 1595 return (NULL);
1606 //eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D
1607 1596
1608 fix_auto_apply (m); /* Chests which open as default */ 1597 fix_auto_apply (m); /* Chests which open as default */
1609 1598
1610 /* If a player unique map, no extra unique object file to load. 1599 /* If a player unique map, no extra unique object file to load.
1611 * if from the editor, likewise. 1600 * if from the editor, likewise.
1747 if (first_map->in_memory == MAP_SAVING) 1736 if (first_map->in_memory == MAP_SAVING)
1748 first_map->in_memory = MAP_IN_MEMORY; 1737 first_map->in_memory = MAP_IN_MEMORY;
1749 delete_map (first_map); 1738 delete_map (first_map);
1750 real_maps++; 1739 real_maps++;
1751 } 1740 }
1741
1752 LOG (llevDebug, "free_all_maps: Freed %d maps\n", real_maps); 1742 LOG (llevDebug, "free_all_maps: Freed %d maps\n", real_maps);
1753} 1743}
1754 1744
1755/* change_map_light() - used to change map light level (darkness) 1745/* change_map_light() - used to change map light level (darkness)
1756 * up or down. Returns true if successful. It should now be 1746 * up or down. Returns true if successful. It should now be
1973} 1963}
1974 1964
1975void 1965void
1976set_map_reset_time (maptile *map) 1966set_map_reset_time (maptile *map)
1977{ 1967{
1978 int timeout;
1979
1980 timeout = map->reset_timeout; 1968 int timeout = map->reset_timeout;
1969
1981 if (timeout <= 0) 1970 if (timeout <= 0)
1982 timeout = MAP_DEFAULTRESET; 1971 timeout = MAP_DEFAULTRESET;
1983 if (timeout >= MAP_MAXRESET) 1972 if (timeout >= MAP_MAXRESET)
1984 timeout = MAP_MAXRESET; 1973 timeout = MAP_MAXRESET;
1974
1985 map->reset_time = time (0) + timeout; 1975 map->reset_time = time (0) + timeout;
1986} 1976}
1987 1977
1988/* this updates the orig_map->tile_map[tile_num] value after loading 1978/* this updates the orig_map->tile_map[tile_num] value after loading
1989 * the map. It also takes care of linking back the freshly loaded 1979 * the map. It also takes care of linking back the freshly loaded

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines