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.54 by root, Wed Dec 27 13:13:46 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 for_all_maps (m)
659 if (m->next = this)
660 {
661 m->next = next;
662 break;
663 }
651} 664}
652 665
653/* 666/*
654 * Allocates, initialises, and returns a pointer to a maptile. 667 * Allocates, initialises, and returns a pointer to a maptile.
655 * Modified to no longer take a path option which was not being 668 * Modified to no longer take a path option which was not being
656 * used anyways. MSW 2001-07-01 669 * used anyways. MSW 2001-07-01
657 */ 670 */
658maptile * 671maptile *
659get_linked_map (void) 672get_linked_map (void)
660{ 673{
661 maptile *mp, *map = new maptile; 674 maptile *map = new maptile;
662 675 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; 676 return map;
671} 677}
672 678
673/* 679/*
674 * Allocates the arrays contained in a maptile. 680 * Allocates the arrays contained in a maptile.
685 * that is their poor assumption. 691 * that is their poor assumption.
686 */ 692 */
687 if (spaces) 693 if (spaces)
688 { 694 {
689 LOG (llevError, "allocate_map called with already allocated map (%s)\n", path); 695 LOG (llevError, "allocate_map called with already allocated map (%s)\n", path);
690 free (spaces); 696 sfree (spaces, size ());
691 } 697 }
692 698
693 spaces = (mapspace *) 699 spaces = salloc0<mapspace> (size ());
694 calloc (1, width * height * sizeof (mapspace));
695
696 if (!spaces)
697 fatal (OUT_OF_MEMORY);
698} 700}
699 701
700/* Create and returns a map of the specific size. Used 702/* Create and returns a map of the specific size. Used
701 * in random map code and the editor. 703 * in random map code and the editor.
702 */ 704 */
735 p = strchr (p, ';'); 737 p = strchr (p, ';');
736 number_of_entries++; 738 number_of_entries++;
737 if (p) 739 if (p)
738 p++; 740 p++;
739 } 741 }
742
740 p = shop_string; 743 p = shop_string;
741 strip_endline (p); 744 strip_endline (p);
742 items = new shopitems[number_of_entries + 1]; 745 items = new shopitems[number_of_entries + 1];
743 for (i = 0; i < number_of_entries; i++) 746 for (i = 0; i < number_of_entries; i++)
744 { 747 {
745 if (!p) 748 if (!p)
746 { 749 {
747 LOG (llevError, "parse_shop_string: I seem to have run out of string, that shouldn't happen.\n"); 750 LOG (llevError, "parse_shop_string: I seem to have run out of string, that shouldn't happen.\n");
748 break; 751 break;
749 } 752 }
753
750 next_semicolon = strchr (p, ';'); 754 next_semicolon = strchr (p, ';');
751 next_colon = strchr (p, ':'); 755 next_colon = strchr (p, ':');
752 /* if there is a stregth specified, figure out what it is, we'll need it soon. */ 756 /* 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)) 757 if (next_colon && (!next_semicolon || next_colon < next_semicolon))
754 items[i].strength = atoi (strchr (p, ':') + 1); 758 items[i].strength = atoi (strchr (p, ':') + 1);
781 * the next entry while we're at it, better print a warning 785 * the next entry while we're at it, better print a warning
782 */ 786 */
783 LOG (llevError, "invalid type %s defined in shopitems in string %s\n", p, input_string); 787 LOG (llevError, "invalid type %s defined in shopitems in string %s\n", p, input_string);
784 } 788 }
785 } 789 }
790
786 items[i].index = number_of_entries; 791 items[i].index = number_of_entries;
787 if (next_semicolon) 792 if (next_semicolon)
788 p = ++next_semicolon; 793 p = ++next_semicolon;
789 else 794 else
790 p = NULL; 795 p = NULL;
791 } 796 }
797
792 free (shop_string); 798 free (shop_string);
793 return items; 799 return items;
794} 800}
795 801
796/* opposite of parse string, this puts the string that was originally fed in to 802/* opposite of parse string, this puts the string that was originally fed in to
805 for (i = 0; i < m->shopitems[0].index; i++) 811 for (i = 0; i < m->shopitems[0].index; i++)
806 { 812 {
807 if (m->shopitems[i].typenum) 813 if (m->shopitems[i].typenum)
808 { 814 {
809 if (m->shopitems[i].strength) 815 if (m->shopitems[i].strength)
810 {
811 sprintf (tmp, "%s:%d;", m->shopitems[i].name, m->shopitems[i].strength); 816 sprintf (tmp, "%s:%d;", m->shopitems[i].name, m->shopitems[i].strength);
812 }
813 else 817 else
814 sprintf (tmp, "%s;", m->shopitems[i].name); 818 sprintf (tmp, "%s;", m->shopitems[i].name);
815 } 819 }
816 else 820 else
817 { 821 {
818 if (m->shopitems[i].strength) 822 if (m->shopitems[i].strength)
819 {
820 sprintf (tmp, "*:%d;", m->shopitems[i].strength); 823 sprintf (tmp, "*:%d;", m->shopitems[i].strength);
821 }
822 else 824 else
823 sprintf (tmp, "*"); 825 sprintf (tmp, "*");
824 } 826 }
827
825 strcat (output_string, tmp); 828 strcat (output_string, tmp);
826 } 829 }
827} 830}
828 831
829/* This loads the header information of the map. The header 832/* 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 1100 * 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. 1101 * 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 1102 * MAP_STYLE: style map - don't add active objects, don't add to server
1100 * managed map list. 1103 * managed map list.
1101 */ 1104 */
1102
1103maptile * 1105maptile *
1104load_original_map (const char *filename, int flags) 1106load_original_map (const char *filename, int flags)
1105{ 1107{
1106 maptile *m; 1108 maptile *m;
1107 char pathname[MAX_BUF]; 1109 char pathname[MAX_BUF];
1146/* 1148/*
1147 * Loads a map, which has been loaded earlier, from file. 1149 * Loads a map, which has been loaded earlier, from file.
1148 * Return the map object we load into (this can change from the passed 1150 * Return the map object we load into (this can change from the passed
1149 * option if we can't find the original map) 1151 * option if we can't find the original map)
1150 */ 1152 */
1151
1152static maptile * 1153static maptile *
1153load_temporary_map (maptile *m) 1154load_temporary_map (maptile *m)
1154{ 1155{
1155 char buf[MAX_BUF]; 1156 char buf[MAX_BUF];
1156 1157
1200/* 1201/*
1201 * Loads a map, which has been loaded earlier, from file. 1202 * Loads a map, which has been loaded earlier, from file.
1202 * Return the map object we load into (this can change from the passed 1203 * Return the map object we load into (this can change from the passed
1203 * option if we can't find the original map) 1204 * option if we can't find the original map)
1204 */ 1205 */
1205
1206maptile * 1206maptile *
1207load_overlay_map (const char *filename, maptile *m) 1207load_overlay_map (const char *filename, maptile *m)
1208{ 1208{
1209 char pathname[MAX_BUF]; 1209 char pathname[MAX_BUF];
1210 1210
1260 op->destroy (); 1260 op->destroy ();
1261 } 1261 }
1262 } 1262 }
1263 } 1263 }
1264} 1264}
1265
1266 1265
1267/* 1266/*
1268 * Loads unique objects from file(s) into the map which is in memory 1267 * Loads unique objects from file(s) into the map which is in memory
1269 * m is the map to load unique items into. 1268 * m is the map to load unique items into.
1270 */ 1269 */
1487 // TODO: use new/delete 1486 // TODO: use new/delete
1488 1487
1489 if (flag && m->spaces) 1488 if (flag && m->spaces)
1490 free_all_objects (m); 1489 free_all_objects (m);
1491 1490
1491 sfree (m->spaces, m->size ()), m->spaces = 0;
1492
1492 free (m->name), m->name = 0; 1493 free (m->name), m->name = 0;
1493 free (m->spaces), m->spaces = 0;
1494 free (m->msg), m->msg = 0; 1494 free (m->msg), m->msg = 0;
1495 free (m->maplore), m->maplore = 0; 1495 free (m->maplore), m->maplore = 0;
1496 free (m->shoprace), m->shoprace = 0; 1496 free (m->shoprace), m->shoprace = 0;
1497 delete [] m->shopitems, m->shopitems = 0; 1497 delete [] m->shopitems, m->shopitems = 0;
1498 1498
1499 if (m->buttons) 1499 if (m->buttons)
1500 free_objectlinkpt (m->buttons), m->buttons = 0; 1500 free_objectlinkpt (m->buttons), m->buttons = 0;
1501 1501
1502 for (int i = 0; i < 4; i++) 1502 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; 1503 free (m->tile_path[i]), m->tile_path[i] = 0;
1506
1507 m->tile_map[i] = 0;
1508 }
1509 1504
1510 m->in_memory = MAP_SWAPPED; 1505 m->in_memory = MAP_SWAPPED;
1511} 1506}
1512 1507
1513maptile::~maptile () 1508maptile::~maptile ()
1514{ 1509{
1515 free_map (this, 1); 1510 assert (destroyed ());
1516 free (tmpname);
1517} 1511}
1518 1512
1519void 1513void
1520maptile::do_destroy () 1514maptile::do_destroy ()
1521{ 1515{
1522 attachable::do_destroy (); 1516 attachable::do_destroy ();
1523 1517
1524 free_all_objects (this); 1518 unlink ();
1519
1520 free_map (this, 1);
1521 free (tmpname), tmpname = 0;
1525 1522
1526 /* We need to look through all the maps and see if any maps 1523 /* We need to look through all the maps and see if any maps
1527 * are pointing at this one for tiling information. Since 1524 * are pointing at this one for tiling information. Since
1528 * tiling can be asymetric, we just can not look to see which 1525 * tiling can be asymetric, we just can not look to see which
1529 * maps this map tiles with and clears those. 1526 * maps this map tiles with and clears those.
1530 */ 1527 */
1531 //TODO: non-euclidean-tiling MUST GO 1528 //TODO: non-euclidean-tiling MUST GO
1532 for (maptile *m = first_map; m; m = m->next) 1529 for_all_maps (m)
1533 for (int i = 0; i < 4; i++) 1530 for (int i = 0; i < 4; i++)
1534 if (m->tile_map[i] == this) 1531 if (m->tile_map[i] == this)
1535 m->tile_map[i] = 0; 1532 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} 1533}
1547 1534
1548//TODO: must go 1535//TODO: must go
1549void 1536void
1550delete_map (maptile *m) 1537delete_map (maptile *m)
1598 if (flags & MAP_PLAYER_UNIQUE) 1585 if (flags & MAP_PLAYER_UNIQUE)
1599 LOG (llevDebug, "Trying to load map %s.\n", name); 1586 LOG (llevDebug, "Trying to load map %s.\n", name);
1600 else 1587 else
1601 LOG (llevDebug, "Trying to load map %s.\n", create_pathname (name)); 1588 LOG (llevDebug, "Trying to load map %s.\n", create_pathname (name));
1602 1589
1603 //eval_pv ("$x = Event::time", 1);//D
1604 if (!(m = load_original_map (name, (flags & MAP_PLAYER_UNIQUE)))) 1590 if (!(m = load_original_map (name, (flags & MAP_PLAYER_UNIQUE))))
1605 return (NULL); 1591 return (NULL);
1606 //eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D
1607 1592
1608 fix_auto_apply (m); /* Chests which open as default */ 1593 fix_auto_apply (m); /* Chests which open as default */
1609 1594
1610 /* If a player unique map, no extra unique object file to load. 1595 /* If a player unique map, no extra unique object file to load.
1611 * if from the editor, likewise. 1596 * if from the editor, likewise.
1747 if (first_map->in_memory == MAP_SAVING) 1732 if (first_map->in_memory == MAP_SAVING)
1748 first_map->in_memory = MAP_IN_MEMORY; 1733 first_map->in_memory = MAP_IN_MEMORY;
1749 delete_map (first_map); 1734 delete_map (first_map);
1750 real_maps++; 1735 real_maps++;
1751 } 1736 }
1737
1752 LOG (llevDebug, "free_all_maps: Freed %d maps\n", real_maps); 1738 LOG (llevDebug, "free_all_maps: Freed %d maps\n", real_maps);
1753} 1739}
1754 1740
1755/* change_map_light() - used to change map light level (darkness) 1741/* change_map_light() - used to change map light level (darkness)
1756 * up or down. Returns true if successful. It should now be 1742 * up or down. Returns true if successful. It should now be

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines