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.45 by root, Wed Dec 20 09:14:21 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>
32 31
33/* 32/*
34 * Returns the maptile which has a name matching the given argument. 33 * Returns the maptile which has a name matching the given argument.
35 * return NULL if no match is found. 34 * return NULL if no match is found.
36 */ 35 */
37
38maptile * 36maptile *
39has_been_loaded (const char *name) 37has_been_loaded (const char *name)
40{ 38{
41 maptile *map;
42
43 if (!name || !*name) 39 if (!name || !*name)
44 return 0; 40 return 0;
45 for (map = first_map; map; map = map->next) 41
42 for_all_maps (map)
46 if (!strcmp (name, map->path)) 43 if (!strcmp (name, map->path))
47 break;
48 return (map); 44 return map;
45
46 return 0;
49} 47}
50 48
51/* 49/*
52 * This makes a path absolute outside the world of Crossfire. 50 * This makes a path absolute outside the world of Crossfire.
53 * In other words, it prepends LIBDIR/MAPDIR/ to the given path 51 * In other words, it prepends LIBDIR/MAPDIR/ to the given path
196 194
197void 195void
198dump_map (const maptile *m) 196dump_map (const maptile *m)
199{ 197{
200 LOG (llevError, "Map %s status: %d.\n", m->path, m->in_memory); 198 LOG (llevError, "Map %s status: %d.\n", m->path, m->in_memory);
201 LOG (llevError, "Size: %dx%d Start: %d,%d\n", MAP_WIDTH (m), MAP_HEIGHT (m), MAP_ENTER_X (m), MAP_ENTER_Y (m)); 199 LOG (llevError, "Size: %dx%d Start: %d,%d\n", m->width, m->height, m->enter_x, m->enter_y);
202 200
203 if (m->msg != NULL) 201 if (m->msg != NULL)
204 LOG (llevError, "Message:\n%s", m->msg); 202 LOG (llevError, "Message:\n%s", m->msg);
205 203
206 if (m->maplore != NULL) 204 if (m->maplore != NULL)
220 */ 218 */
221 219
222void 220void
223dump_all_maps (void) 221dump_all_maps (void)
224{ 222{
225 maptile *m; 223 for_all_maps (m)
226
227 for (m = first_map; m != NULL; m = m->next)
228 {
229 dump_map (m); 224 dump_map (m);
230 }
231} 225}
232 226
233/* This rolls up wall, blocks_magic, blocks_view, etc, all into 227/* This rolls up wall, blocks_magic, blocks_view, etc, all into
234 * one function that just returns a P_.. value (see map.h) 228 * one function that just returns a P_.. value (see map.h)
235 * it will also do map translation for tiled maps, returning 229 * it will also do map translation for tiled maps, returning
239 * is needed. The case of not passing values is if we're just 233 * is needed. The case of not passing values is if we're just
240 * checking for the existence of something on those spaces, but 234 * checking for the existence of something on those spaces, but
241 * don't expect to insert/remove anything from those spaces. 235 * don't expect to insert/remove anything from those spaces.
242 */ 236 */
243int 237int
244get_map_flags (maptile *oldmap, maptile **newmap, sint16 x, sint16 y, sint16 * nx, sint16 * ny) 238get_map_flags (maptile *oldmap, maptile **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)
245{ 239{
246 sint16 newx, newy; 240 sint16 newx, newy;
247 int retval = 0; 241 int retval = 0;
248 maptile *mp; 242 maptile *mp;
249 243
250 if (out_of_map (oldmap, x, y))
251 return P_OUT_OF_MAP;
252 newx = x; 244 newx = x;
253 newy = y; 245 newy = y;
246
254 mp = get_map_from_coord (oldmap, &newx, &newy); 247 mp = get_map_from_coord (oldmap, &newx, &newy);
248
249 if (!mp)
250 return P_OUT_OF_MAP;
251
255 if (mp != oldmap) 252 if (mp != oldmap)
256 retval |= P_NEW_MAP; 253 retval |= P_NEW_MAP;
257 if (newmap)
258 *newmap = mp;
259 if (nx)
260 *nx = newx;
261 if (ny)
262 *ny = newy;
263 254
264 retval |= mp->spaces[newx + mp->width * newy].flags; 255 if (newmap) *newmap = mp;
256 if (nx) *nx = newx;
257 if (ny) *ny = newy;
265 258
266 return retval; 259 return retval | mp->at (newx, newy).flags ();
267} 260}
268 261
269/* 262/*
270 * Returns true if the given coordinate is blocked except by the 263 * Returns true if the given coordinate is blocked except by the
271 * object passed is not blocking. This is used with 264 * object passed is not blocking. This is used with
294 } 287 }
295 288
296 /* Save some cycles - instead of calling get_map_flags(), just get the value 289 /* Save some cycles - instead of calling get_map_flags(), just get the value
297 * directly. 290 * directly.
298 */ 291 */
299 mflags = m->spaces[sx + m->width * sy].flags; 292 mflags = m->at (sx, sy).flags ();
300 293
301 blocked = GET_MAP_MOVE_BLOCK (m, sx, sy); 294 blocked = GET_MAP_MOVE_BLOCK (m, sx, sy);
302 295
303 /* If space is currently not blocked by anything, no need to 296 /* If space is currently not blocked by anything, no need to
304 * go further. Not true for players - all sorts of special 297 * go further. Not true for players - all sorts of special
412 flag = get_map_flags (m, &m1, x, y, &sx, &sy); 405 flag = get_map_flags (m, &m1, x, y, &sx, &sy);
413 if (flag & P_OUT_OF_MAP) 406 if (flag & P_OUT_OF_MAP)
414 return P_OUT_OF_MAP; 407 return P_OUT_OF_MAP;
415 408
416 /* don't have object, so don't know what types would block */ 409 /* don't have object, so don't know what types would block */
417 return (GET_MAP_MOVE_BLOCK (m1, sx, sy)); 410 return m1->at (sx, sy).move_block;
418 } 411 }
419 412
420 for (tmp = ob->arch; tmp != NULL; tmp = tmp->more) 413 for (tmp = ob->arch; tmp; tmp = tmp->more)
421 { 414 {
422 flag = get_map_flags (m, &m1, x + tmp->clone.x, y + tmp->clone.y, &sx, &sy); 415 flag = get_map_flags (m, &m1, x + tmp->clone.x, y + tmp->clone.y, &sx, &sy);
423 416
424 if (flag & P_OUT_OF_MAP) 417 if (flag & P_OUT_OF_MAP)
425 return P_OUT_OF_MAP; 418 return P_OUT_OF_MAP;
426 if (flag & P_IS_ALIVE) 419 if (flag & P_IS_ALIVE)
427 return P_IS_ALIVE; 420 return P_IS_ALIVE;
428 421
422 mapspace &ms = m1->at (sx, sy);
423
424
429 /* find_first_free_spot() calls this function. However, often 425 /* find_first_free_spot() calls this function. However, often
430 * ob doesn't have any move type (when used to place exits) 426 * ob doesn't have any move type (when used to place exits)
431 * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work. 427 * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work.
432 */ 428 */
433 429
434 if (ob->move_type == 0 && GET_MAP_MOVE_BLOCK (m1, sx, sy) != MOVE_ALL) 430 if (ob->move_type == 0 && ms.move_block != MOVE_ALL)
435 continue; 431 continue;
436 432
437 /* Note it is intentional that we check ob - the movement type of the 433 /* Note it is intentional that we check ob - the movement type of the
438 * head of the object should correspond for the entire object. 434 * head of the object should correspond for the entire object.
439 */ 435 */
440 if (OB_TYPE_MOVE_BLOCK (ob, GET_MAP_MOVE_BLOCK (m1, sx, sy))) 436 if (OB_TYPE_MOVE_BLOCK (ob, ms.move_block))
441 return P_NO_PASS; 437 return P_NO_PASS;
442 } 438 }
443 439
444 return 0; 440 return 0;
445} 441}
475 * 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
476 * 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
477 * 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
478 * the more sections and not re-add sections for them. 474 * the more sections and not re-add sections for them.
479 */ 475 */
480
481static void 476static void
482link_multipart_objects (maptile *m) 477link_multipart_objects (maptile *m)
483{ 478{
484 int x, y; 479 int x, y;
485 object *tmp, *op, *last, *above; 480 object *tmp, *op, *last, *above;
486 archetype *at; 481 archetype *at;
487 482
488 for (x = 0; x < MAP_WIDTH (m); x++) 483 for (x = 0; x < m->width; x++)
489 for (y = 0; y < MAP_HEIGHT (m); y++) 484 for (y = 0; y < m->height; y++)
490 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = above) 485 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL; tmp = above)
491 { 486 {
492 above = tmp->above; 487 above = tmp->above;
493 488
494 /* already multipart - don't do anything more */ 489 /* already multipart - don't do anything more */
545 { 540 {
546 LOG (llevDebug, "Discarding object without arch: %s\n", op->name ? (const char *) op->name : "(null)"); 541 LOG (llevDebug, "Discarding object without arch: %s\n", op->name ? (const char *) op->name : "(null)");
547 continue; 542 continue;
548 } 543 }
549 544
550
551 switch (i) 545 switch (i)
552 { 546 {
553 case LL_NORMAL: 547 case LL_NORMAL:
554 /* if we are loading an overlay, put the floors on the bottom */ 548 /* if we are loading an overlay, put the floors on the bottom */
555 if ((QUERY_FLAG (op, FLAG_IS_FLOOR) || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY) 549 if ((QUERY_FLAG (op, FLAG_IS_FLOOR) || QUERY_FLAG (op, FLAG_OVERLAY_FLOOR)) && mapflags & MAP_OVERLAY)
601 * Modified by MSW 2001-07-01 to do in a single pass - reduces code, 595 * Modified by MSW 2001-07-01 to do in a single pass - reduces code,
602 * and we only save the head of multi part objects - this is needed 596 * and we only save the head of multi part objects - this is needed
603 * in order to do map tiling properly. 597 * in order to do map tiling properly.
604 */ 598 */
605void 599void
606save_objects (maptile *m, object_freezer & fp, object_freezer & fp2, int flag) 600save_objects (maptile *m, object_freezer &fp, object_freezer &fp2, int flag)
607{ 601{
608 int i, j = 0, unique = 0; 602 int i, j = 0, unique = 0;
609 object *op; 603 object *op;
610 604
611 /* first pass - save one-part objects */ 605 /* first pass - save one-part objects */
612 for (i = 0; i < MAP_WIDTH (m); i++) 606 for (i = 0; i < m->width; i++)
613 for (j = 0; j < MAP_HEIGHT (m); j++) 607 for (j = 0; j < m->height; j++)
614 { 608 {
615 unique = 0; 609 unique = 0;
610
616 for (op = GET_MAP_OB (m, i, j); op; op = op->above) 611 for (op = m->at (i, j).bot; op; op = op->above)
617 { 612 {
618 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE)) 613 if (op->flag [FLAG_UNIQUE] && op->flag [FLAG_IS_FLOOR])
619 unique = 1; 614 unique = 1;
620 615
621 if (op->type == PLAYER) 616 if (!op->can_map_save ())
622 continue; 617 continue;
623 618
624 if (op->head || op->owner)
625 continue;
626
627 if (unique || QUERY_FLAG (op, FLAG_UNIQUE)) 619 if (unique || op->flag [FLAG_UNIQUE])
628 save_object (fp2, op, 3); 620 save_object (fp2, op, 1);
629 else if (flag == 0 || (flag == 2 && (!QUERY_FLAG (op, FLAG_OBJ_ORIGINAL) && !QUERY_FLAG (op, FLAG_UNPAID)))) 621 else if (flag == 0 || (flag == 2 && (!op->flag [FLAG_OBJ_ORIGINAL] && !op->flag [FLAG_UNPAID])))
630 save_object (fp, op, 3); 622 save_object (fp, op, 1);
631 } 623 }
632 } 624 }
633} 625}
634 626
635maptile::maptile () 627maptile::maptile ()
636{ 628{
637 in_memory = MAP_SWAPPED; 629 in_memory = MAP_SWAPPED;
630
638 /* 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
639 * map archetype. Mimic that behaviour. 632 * map archetype. Mimic that behaviour.
640 */ 633 */
641 MAP_WIDTH (this) = 16; 634 width = 16;
642 MAP_HEIGHT (this) = 16; 635 height = 16;
643 MAP_RESET_TIMEOUT (this) = 0; 636 reset_timeout = 0;
644 MAP_TIMEOUT (this) = 300; 637 timeout = 300;
645 MAP_ENTER_X (this) = 0; 638 enter_x = 0;
646 MAP_ENTER_Y (this) = 0; 639 enter_y = 0;
647 /*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 */
648 MAP_WORLDPARTX (this) = -1; 641 worldpartx = -1;
649 MAP_WORLDPARTY (this) = -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 }
650} 668}
651 669
652/* 670/*
653 * Allocates, initialises, and returns a pointer to a maptile. 671 * Allocates, initialises, and returns a pointer to a maptile.
654 * 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
655 * used anyways. MSW 2001-07-01 673 * used anyways. MSW 2001-07-01
656 */ 674 */
657maptile * 675maptile *
658get_linked_map (void) 676get_linked_map (void)
659{ 677{
660 maptile *mp, *map = new maptile; 678 maptile *map = new maptile;
661 679 map->link ();
662 for (mp = first_map; mp && mp->next; mp = mp->next);
663
664 if (mp == NULL)
665 first_map = map;
666 else
667 mp->next = map;
668
669 return map; 680 return map;
670} 681}
671 682
672/* 683/*
673 * Allocates the arrays contained in a maptile. 684 * Allocates the arrays contained in a maptile.
684 * that is their poor assumption. 695 * that is their poor assumption.
685 */ 696 */
686 if (spaces) 697 if (spaces)
687 { 698 {
688 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);
689 free (spaces); 700 sfree (spaces, size ());
690 } 701 }
691 702
692 spaces = (mapspace *) 703 spaces = salloc0<mapspace> (size ());
693 calloc (1, width * height * sizeof (mapspace));
694
695 if (!spaces)
696 fatal (OUT_OF_MEMORY);
697} 704}
698 705
699/* Create and returns a map of the specific size. Used 706/* Create and returns a map of the specific size. Used
700 * in random map code and the editor. 707 * in random map code and the editor.
701 */ 708 */
702maptile * 709maptile *
703get_empty_map (int sizex, int sizey) 710get_empty_map (int sizex, int sizey)
704{ 711{
705 maptile *m = get_linked_map (); 712 maptile *m = get_linked_map ();
706 713
707 m->width = sizex; 714 m->width = sizex;
708 m->height = sizey; 715 m->height = sizey;
709 m->in_memory = MAP_SWAPPED; 716 m->in_memory = MAP_SWAPPED;
717
710 m->allocate (); 718 m->allocate ();
711 719
712 return m; 720 return m;
713} 721}
714 722
715/* 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
716 * 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
717 * at a later date. 725 * at a later date.
718 * Called by parse_map_headers below. 726 * Called by parse_map_headers below.
719 */ 727 */
720
721static shopitems * 728static shopitems *
722parse_shop_string (const char *input_string) 729parse_shop_string (const char *input_string)
723{ 730{
724 char *shop_string, *p, *q, *next_semicolon, *next_colon; 731 char *shop_string, *p, *q, *next_semicolon, *next_colon;
725 shopitems *items = NULL; 732 shopitems *items = NULL;
734 p = strchr (p, ';'); 741 p = strchr (p, ';');
735 number_of_entries++; 742 number_of_entries++;
736 if (p) 743 if (p)
737 p++; 744 p++;
738 } 745 }
746
739 p = shop_string; 747 p = shop_string;
740 strip_endline (p); 748 strip_endline (p);
741 items = new shopitems[number_of_entries + 1]; 749 items = new shopitems[number_of_entries + 1];
742 for (i = 0; i < number_of_entries; i++) 750 for (i = 0; i < number_of_entries; i++)
743 { 751 {
744 if (!p) 752 if (!p)
745 { 753 {
746 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");
747 break; 755 break;
748 } 756 }
757
749 next_semicolon = strchr (p, ';'); 758 next_semicolon = strchr (p, ';');
750 next_colon = strchr (p, ':'); 759 next_colon = strchr (p, ':');
751 /* 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. */
752 if (next_colon && (!next_semicolon || next_colon < next_semicolon)) 761 if (next_colon && (!next_semicolon || next_colon < next_semicolon))
753 items[i].strength = atoi (strchr (p, ':') + 1); 762 items[i].strength = atoi (strchr (p, ':') + 1);
780 * 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
781 */ 790 */
782 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);
783 } 792 }
784 } 793 }
794
785 items[i].index = number_of_entries; 795 items[i].index = number_of_entries;
786 if (next_semicolon) 796 if (next_semicolon)
787 p = ++next_semicolon; 797 p = ++next_semicolon;
788 else 798 else
789 p = NULL; 799 p = NULL;
790 } 800 }
801
791 free (shop_string); 802 free (shop_string);
792 return items; 803 return items;
793} 804}
794 805
795/* 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
804 for (i = 0; i < m->shopitems[0].index; i++) 815 for (i = 0; i < m->shopitems[0].index; i++)
805 { 816 {
806 if (m->shopitems[i].typenum) 817 if (m->shopitems[i].typenum)
807 { 818 {
808 if (m->shopitems[i].strength) 819 if (m->shopitems[i].strength)
809 {
810 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);
811 }
812 else 821 else
813 sprintf (tmp, "%s;", m->shopitems[i].name); 822 sprintf (tmp, "%s;", m->shopitems[i].name);
814 } 823 }
815 else 824 else
816 { 825 {
817 if (m->shopitems[i].strength) 826 if (m->shopitems[i].strength)
818 {
819 sprintf (tmp, "*:%d;", m->shopitems[i].strength); 827 sprintf (tmp, "*:%d;", m->shopitems[i].strength);
820 }
821 else 828 else
822 sprintf (tmp, "*"); 829 sprintf (tmp, "*");
823 } 830 }
831
824 strcat (output_string, tmp); 832 strcat (output_string, tmp);
825 } 833 }
826} 834}
827 835
828/* This loads the header information of the map. The header 836/* This loads the header information of the map. The header
1096 * 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
1097 * cases, no matter if this flag is set or not. 1105 * cases, no matter if this flag is set or not.
1098 * 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
1099 * managed map list. 1107 * managed map list.
1100 */ 1108 */
1101
1102maptile * 1109maptile *
1103load_original_map (const char *filename, int flags) 1110load_original_map (const char *filename, int flags)
1104{ 1111{
1105 maptile *m; 1112 maptile *m;
1106 char pathname[MAX_BUF]; 1113 char pathname[MAX_BUF];
1124 strcpy (m->path, filename); 1131 strcpy (m->path, filename);
1125 if (load_map_header (thawer, m)) 1132 if (load_map_header (thawer, m))
1126 { 1133 {
1127 LOG (llevError, "Error loading map header for %s, flags=%d\n", filename, flags); 1134 LOG (llevError, "Error loading map header for %s, flags=%d\n", filename, flags);
1128 delete_map (m); 1135 delete_map (m);
1129 return NULL; 1136 return 0;
1130 } 1137 }
1131 1138
1132 m->allocate (); 1139 m->allocate ();
1133 1140
1134 m->in_memory = MAP_LOADING; 1141 m->in_memory = MAP_LOADING;
1135 load_objects (m, thawer, flags & (MAP_BLOCK | MAP_STYLE)); 1142 load_objects (m, thawer, flags & (MAP_BLOCK | MAP_STYLE));
1136 1143
1137 m->in_memory = MAP_IN_MEMORY; 1144 m->in_memory = MAP_IN_MEMORY;
1138 if (!MAP_DIFFICULTY (m)) 1145 if (!m->difficulty)
1139 MAP_DIFFICULTY (m) = calculate_difficulty (m); 1146 m->difficulty = calculate_difficulty (m);
1140 set_map_reset_time (m); 1147 set_map_reset_time (m);
1141 m->instantiate (); 1148 m->instantiate ();
1142 return (m); 1149 return (m);
1143} 1150}
1144 1151
1145/* 1152/*
1146 * Loads a map, which has been loaded earlier, from file. 1153 * Loads a map, which has been loaded earlier, from file.
1147 * 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
1148 * option if we can't find the original map) 1155 * option if we can't find the original map)
1149 */ 1156 */
1150
1151static maptile * 1157static maptile *
1152load_temporary_map (maptile *m) 1158load_temporary_map (maptile *m)
1153{ 1159{
1154 char buf[MAX_BUF]; 1160 char buf[MAX_BUF];
1155 1161
1199/* 1205/*
1200 * Loads a map, which has been loaded earlier, from file. 1206 * Loads a map, which has been loaded earlier, from file.
1201 * 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
1202 * option if we can't find the original map) 1208 * option if we can't find the original map)
1203 */ 1209 */
1204
1205maptile * 1210maptile *
1206load_overlay_map (const char *filename, maptile *m) 1211load_overlay_map (const char *filename, maptile *m)
1207{ 1212{
1208 char pathname[MAX_BUF]; 1213 char pathname[MAX_BUF];
1209 1214
1217 if (load_map_header (thawer, m)) 1222 if (load_map_header (thawer, m))
1218 { 1223 {
1219 LOG (llevError, "Error loading map header for overlay %s (%s)\n", m->path, pathname); 1224 LOG (llevError, "Error loading map header for overlay %s (%s)\n", m->path, pathname);
1220 delete_map (m); 1225 delete_map (m);
1221 m = load_original_map (m->path, 0); 1226 m = load_original_map (m->path, 0);
1222 return NULL; 1227 return 0;
1223 } 1228 }
1224 /*m->allocate ();*/ 1229 /*m->allocate ();*/
1225 1230
1226 m->in_memory = MAP_LOADING; 1231 m->in_memory = MAP_LOADING;
1227 load_objects (m, thawer, MAP_OVERLAY); 1232 load_objects (m, thawer, MAP_OVERLAY);
1239delete_unique_items (maptile *m) 1244delete_unique_items (maptile *m)
1240{ 1245{
1241 int i, j, unique; 1246 int i, j, unique;
1242 object *op, *next; 1247 object *op, *next;
1243 1248
1244 for (i = 0; i < MAP_WIDTH (m); i++) 1249 for (i = 0; i < m->width; i++)
1245 for (j = 0; j < MAP_HEIGHT (m); j++) 1250 for (j = 0; j < m->height; j++)
1246 { 1251 {
1247 unique = 0; 1252 unique = 0;
1248 1253
1249 for (op = GET_MAP_OB (m, i, j); op; op = next) 1254 for (op = GET_MAP_OB (m, i, j); op; op = next)
1250 { 1255 {
1253 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE)) 1258 if (QUERY_FLAG (op, FLAG_IS_FLOOR) && QUERY_FLAG (op, FLAG_UNIQUE))
1254 unique = 1; 1259 unique = 1;
1255 1260
1256 if (op->head == NULL && (QUERY_FLAG (op, FLAG_UNIQUE) || unique)) 1261 if (op->head == NULL && (QUERY_FLAG (op, FLAG_UNIQUE) || unique))
1257 { 1262 {
1258 clean_object (op); 1263 op->destroy_inv (false);
1259
1260 if (QUERY_FLAG (op, FLAG_IS_LINKED))
1261 remove_button_link (op);
1262
1263 op->destroy (); 1264 op->destroy ();
1264 } 1265 }
1265 } 1266 }
1266 } 1267 }
1267} 1268}
1268 1269
1269
1270/* 1270/*
1271 * 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
1272 * m is the map to load unique items into. 1272 * m is the map to load unique items into.
1273 */ 1273 */
1274static void 1274static void
1293 return; 1293 return;
1294 1294
1295 m->in_memory = MAP_LOADING; 1295 m->in_memory = MAP_LOADING;
1296 if (m->tmpname == NULL) /* if we have loaded unique items from */ 1296 if (m->tmpname == NULL) /* if we have loaded unique items from */
1297 delete_unique_items (m); /* original map before, don't duplicate them */ 1297 delete_unique_items (m); /* original map before, don't duplicate them */
1298
1298 load_objects (m, thawer, 0); 1299 load_objects (m, thawer, 0);
1299 1300
1300 m->in_memory = MAP_IN_MEMORY; 1301 m->in_memory = MAP_IN_MEMORY;
1301} 1302}
1302
1303 1303
1304/* 1304/*
1305 * Saves a map to file. If flag is set, it is saved into the same 1305 * Saves a map to file. If flag is set, it is saved into the same
1306 * file it was (originally) loaded from. Otherwise a temporary 1306 * file it was (originally) loaded from. Otherwise a temporary
1307 * filename will be genarated, and the file will be stored there. 1307 * filename will be genarated, and the file will be stored there.
1308 * The temporary filename will be stored in the maptileure. 1308 * The temporary filename will be stored in the maptileure.
1309 * If the map is unique, we also save to the filename in the map 1309 * If the map is unique, we also save to the filename in the map
1310 * (this should have been updated when first loaded) 1310 * (this should have been updated when first loaded)
1311 */ 1311 */
1312
1313int 1312int
1314new_save_map (maptile *m, int flag) 1313new_save_map (maptile *m, int flag)
1315{ 1314{
1316 char filename[MAX_BUF], buf[MAX_BUF], shop[MAX_BUF]; 1315 char filename[MAX_BUF], buf[MAX_BUF], shop[MAX_BUF];
1317 int i; 1316 int i;
1449 freezer.save (filename); 1448 freezer.save (filename);
1450 1449
1451 return 0; 1450 return 0;
1452} 1451}
1453 1452
1454
1455/*
1456 * Remove and free all objects in the inventory of the given object.
1457 * object.c ?
1458 */
1459
1460void
1461clean_object (object *op)
1462{
1463 object *tmp, *next;
1464
1465 for (tmp = op->inv; tmp; tmp = next)
1466 {
1467 next = tmp->below;
1468
1469 clean_object (tmp);
1470 if (QUERY_FLAG (tmp, FLAG_IS_LINKED))
1471 remove_button_link (tmp);
1472
1473 tmp->destroy ();
1474 }
1475}
1476
1477/* 1453/*
1478 * Remove and free all objects in the given map. 1454 * Remove and free all objects in the given map.
1479 */ 1455 */
1480
1481void 1456void
1482free_all_objects (maptile *m) 1457free_all_objects (maptile *m)
1483{ 1458{
1484 int i, j; 1459 if (!m->spaces)
1485 object *op; 1460 return;
1486 1461
1487 for (i = 0; i < MAP_WIDTH (m); i++) 1462 for (int i = 0; i < m->width; i++)
1488 for (j = 0; j < MAP_HEIGHT (m); j++) 1463 for (int j = 0; j < m->height; j++)
1489 { 1464 {
1490 object *previous_obj = NULL; 1465 mapspace &ms = m->at (i, j);
1491 1466
1492 while ((op = GET_MAP_OB (m, i, j)) != NULL) 1467 while (object *op = ms.bot)
1493 { 1468 {
1494 if (op == previous_obj)
1495 {
1496 LOG (llevDebug, "free_all_objects: Link error, bailing out.\n");
1497 break;
1498 }
1499
1500 previous_obj = op;
1501
1502 if (op->head != NULL) 1469 if (op->head)
1503 op = op->head; 1470 op = op->head;
1504 1471
1505 /* If the map isn't in memory, free_object will remove and 1472 op->destroy_inv (false);
1506 * free objects in op's inventory. So let it do the job.
1507 */
1508 if (m->in_memory == MAP_IN_MEMORY)
1509 clean_object (op);
1510
1511 op->destroy (); 1473 op->destroy ();
1512 } 1474 }
1513 } 1475 }
1514} 1476}
1515 1477
1516/* 1478/*
1517 * Frees everything allocated by the given maptileure. 1479 * Frees everything allocated by the given maptileure.
1518 * don't free tmpname - our caller is left to do that 1480 * don't free tmpname - our caller is left to do that
1519 */ 1481 */
1520
1521void 1482void
1522free_map (maptile *m, int flag) 1483free_map (maptile *m, int flag)
1523{ 1484{
1524 int i; 1485 if (!m->in_memory) //TODO: makes no sense to me?
1525
1526 if (!m->in_memory)
1527 {
1528 LOG (llevError, "Trying to free freed map.\n");
1529 return; 1486 return;
1530 } 1487
1488 m->in_memory = MAP_SAVING;
1531 1489
1532 // TODO: use new/delete 1490 // TODO: use new/delete
1533#define FREE_AND_CLEAR(p) { free (p); p = NULL; }
1534 1491
1535 if (flag && m->spaces) 1492 if (flag && m->spaces)
1536 free_all_objects (m); 1493 free_all_objects (m);
1537 if (m->name)
1538 FREE_AND_CLEAR (m->name);
1539 if (m->spaces)
1540 FREE_AND_CLEAR (m->spaces);
1541 if (m->msg)
1542 FREE_AND_CLEAR (m->msg);
1543 if (m->maplore)
1544 FREE_AND_CLEAR (m->maplore);
1545 1494
1546 delete [] m->shopitems; 1495 sfree (m->spaces, m->size ()), m->spaces = 0;
1547 m->shopitems = 0;
1548 1496
1549 if (m->shoprace) 1497 free (m->name), m->name = 0;
1550 FREE_AND_CLEAR (m->shoprace); 1498 free (m->msg), m->msg = 0;
1499 free (m->maplore), m->maplore = 0;
1500 free (m->shoprace), m->shoprace = 0;
1501 delete [] m->shopitems, m->shopitems = 0;
1551 1502
1552 if (m->buttons) 1503 if (m->buttons)
1553 free_objectlinkpt (m->buttons); 1504 free_objectlinkpt (m->buttons), m->buttons = 0;
1554 1505
1555 m->buttons = NULL;
1556
1557 for (i = 0; i < 4; i++) 1506 for (int i = 0; i < 4; i++)
1558 { 1507 free (m->tile_path[i]), m->tile_path[i] = 0;
1559 if (m->tile_path[i])
1560 FREE_AND_CLEAR (m->tile_path[i]);
1561 m->tile_map[i] = NULL;
1562 }
1563 1508
1564 m->in_memory = MAP_SWAPPED; 1509 m->in_memory = MAP_SWAPPED;
1565
1566#undef FREE_AND_CLEAR
1567
1568} 1510}
1569 1511
1570/* 1512maptile::~maptile ()
1571 * function: vanish maptile 1513{
1572 * m : pointer to maptile, if NULL no action 1514 assert (destroyed ());
1573 * this deletes all the data on the map (freeing pointers) 1515}
1574 * and then removes this map from the global linked list of maps. 1516
1517void
1518maptile::do_destroy ()
1519{
1520 attachable::do_destroy ();
1521
1522 unlink ();
1523
1524 free_map (this, 1);
1525 free (tmpname), tmpname = 0;
1526
1527 /* We need to look through all the maps and see if any maps
1528 * are pointing at this one for tiling information. Since
1529 * tiling can be asymetric, we just can not look to see which
1530 * maps this map tiles with and clears those.
1575 */ 1531 */
1532 //TODO: non-euclidean-tiling MUST GO
1533 for_all_maps (m)
1534 for (int i = 0; i < 4; i++)
1535 if (m->tile_map[i] == this)
1536 m->tile_map[i] = 0;
1537}
1576 1538
1539//TODO: must go
1577void 1540void
1578delete_map (maptile *m) 1541delete_map (maptile *m)
1579{ 1542{
1580 maptile *tmp, *last;
1581 int i;
1582
1583 if (!m) 1543 if (m)
1584 return; 1544 m->destroy ();
1585
1586 m->clear ();
1587
1588 if (m->in_memory == MAP_IN_MEMORY)
1589 {
1590 /* change to MAP_SAVING, even though we are not,
1591 * so that remove_ob doesn't do as much work.
1592 */
1593 m->in_memory = MAP_SAVING;
1594 free_map (m, 1);
1595 }
1596 /* move this out of free_map, since tmpname can still be needed if
1597 * the map is swapped out.
1598 */
1599 if (m->tmpname)
1600 {
1601 free (m->tmpname);
1602 m->tmpname = NULL;
1603 }
1604 last = NULL;
1605 /* We need to look through all the maps and see if any maps
1606 * are pointing at this one for tiling information. Since
1607 * tiling can be assymetric, we just can not look to see which
1608 * maps this map tiles with and clears those.
1609 */
1610 for (tmp = first_map; tmp != NULL; tmp = tmp->next)
1611 {
1612 if (tmp->next == m)
1613 last = tmp;
1614
1615 /* This should hopefully get unrolled on a decent compiler */
1616 for (i = 0; i < 4; i++)
1617 if (tmp->tile_map[i] == m)
1618 tmp->tile_map[i] = NULL;
1619 }
1620
1621 /* If last is null, then this should be the first map in the list */
1622 if (!last)
1623 {
1624 if (m == first_map)
1625 first_map = m->next;
1626 else
1627 /* m->path is a static char, so should hopefully still have
1628 * some useful data in it.
1629 */
1630 LOG (llevError, "delete_map: Unable to find map %s in list\n", m->path);
1631 }
1632 else
1633 last->next = m->next;
1634
1635 delete m;
1636} 1545}
1637 1546
1638/* 1547/*
1639 * Makes sure the given map is loaded and swapped in. 1548 * Makes sure the given map is loaded and swapped in.
1640 * name is path name of the map. 1549 * name is path name of the map.
1647 * Returns a pointer to the given map. 1556 * Returns a pointer to the given map.
1648 */ 1557 */
1649maptile * 1558maptile *
1650ready_map_name (const char *name, int flags) 1559ready_map_name (const char *name, int flags)
1651{ 1560{
1652 maptile *m;
1653
1654 if (!name) 1561 if (!name)
1655 return (NULL); 1562 return 0;
1656 1563
1657 /* Have we been at this level before? */ 1564 /* Have we been at this level before? */
1658 m = has_been_loaded (name); 1565 maptile *m = has_been_loaded (name);
1659 1566
1660 /* Map is good to go, so just return it */ 1567 /* Map is good to go, so just return it */
1661 if (m && (m->in_memory == MAP_LOADING || m->in_memory == MAP_IN_MEMORY)) 1568 if (m && (m->in_memory == MAP_LOADING || m->in_memory == MAP_IN_MEMORY))
1662 {
1663 return m; 1569 return m;
1664 }
1665 1570
1666 /* unique maps always get loaded from their original location, and never 1571 /* unique maps always get loaded from their original location, and never
1667 * a temp location. Likewise, if map_flush is set, or we have never loaded 1572 * a temp location. Likewise, if map_flush is set, or we have never loaded
1668 * this map, load it now. I removed the reset checking from here - 1573 * this map, load it now. I removed the reset checking from here -
1669 * it seems the probability of a player trying to enter a map that should 1574 * it seems the probability of a player trying to enter a map that should
1671 * a bit cleaner (and players probably shouldn't rely on exact timing for 1576 * a bit cleaner (and players probably shouldn't rely on exact timing for
1672 * resets in any case - if they really care, they should use the 'maps command. 1577 * resets in any case - if they really care, they should use the 'maps command.
1673 */ 1578 */
1674 if ((flags & (MAP_FLUSH | MAP_PLAYER_UNIQUE)) || !m) 1579 if ((flags & (MAP_FLUSH | MAP_PLAYER_UNIQUE)) || !m)
1675 { 1580 {
1676
1677 /* first visit or time to reset */ 1581 /* first visit or time to reset */
1678 if (m) 1582 if (m)
1679 { 1583 {
1680 clean_tmp_map (m); /* Doesn't make much difference */ 1584 clean_tmp_map (m); /* Doesn't make much difference */
1681 delete_map (m); 1585 delete_map (m);
1685 if (flags & MAP_PLAYER_UNIQUE) 1589 if (flags & MAP_PLAYER_UNIQUE)
1686 LOG (llevDebug, "Trying to load map %s.\n", name); 1590 LOG (llevDebug, "Trying to load map %s.\n", name);
1687 else 1591 else
1688 LOG (llevDebug, "Trying to load map %s.\n", create_pathname (name)); 1592 LOG (llevDebug, "Trying to load map %s.\n", create_pathname (name));
1689 1593
1690 //eval_pv ("$x = Event::time", 1);//D
1691 if (!(m = load_original_map (name, (flags & MAP_PLAYER_UNIQUE)))) 1594 if (!(m = load_original_map (name, (flags & MAP_PLAYER_UNIQUE))))
1692 return (NULL); 1595 return (NULL);
1693 //eval_pv ("warn \"LOAD \", Event::time - $x", 1);//D
1694 1596
1695 fix_auto_apply (m); /* Chests which open as default */ 1597 fix_auto_apply (m); /* Chests which open as default */
1696 1598
1697 /* 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.
1698 * if from the editor, likewise. 1600 * if from the editor, likewise.
1768 int x, y, i; 1670 int x, y, i;
1769 long monster_cnt = 0; 1671 long monster_cnt = 0;
1770 double avgexp = 0; 1672 double avgexp = 0;
1771 sint64 total_exp = 0; 1673 sint64 total_exp = 0;
1772 1674
1773 if (MAP_DIFFICULTY (m)) 1675 if (m->difficulty)
1774 { 1676 {
1775 LOG (llevDebug, "Using stored map difficulty: %d\n", MAP_DIFFICULTY (m)); 1677 LOG (llevDebug, "Using stored map difficulty: %d\n", m->difficulty);
1776 return MAP_DIFFICULTY (m); 1678 return m->difficulty;
1777 } 1679 }
1778 1680
1779 for (x = 0; x < MAP_WIDTH (m); x++) 1681 for (x = 0; x < m->width; x++)
1780 for (y = 0; y < MAP_HEIGHT (m); y++) 1682 for (y = 0; y < m->height; y++)
1781 for (op = GET_MAP_OB (m, x, y); op != NULL; op = op->above) 1683 for (op = GET_MAP_OB (m, x, y); op != NULL; op = op->above)
1782 { 1684 {
1783 if (QUERY_FLAG (op, FLAG_MONSTER)) 1685 if (QUERY_FLAG (op, FLAG_MONSTER))
1784 { 1686 {
1785 total_exp += op->stats.exp; 1687 total_exp += op->stats.exp;
1834 if (first_map->in_memory == MAP_SAVING) 1736 if (first_map->in_memory == MAP_SAVING)
1835 first_map->in_memory = MAP_IN_MEMORY; 1737 first_map->in_memory = MAP_IN_MEMORY;
1836 delete_map (first_map); 1738 delete_map (first_map);
1837 real_maps++; 1739 real_maps++;
1838 } 1740 }
1741
1839 LOG (llevDebug, "free_all_maps: Freed %d maps\n", real_maps); 1742 LOG (llevDebug, "free_all_maps: Freed %d maps\n", real_maps);
1840} 1743}
1841 1744
1842/* change_map_light() - used to change map light level (darkness) 1745/* change_map_light() - used to change map light level (darkness)
1843 * up or down. Returns true if successful. It should now be 1746 * up or down. Returns true if successful. It should now be
1886 * on the map (what it looks like, whether it blocks magic, 1789 * on the map (what it looks like, whether it blocks magic,
1887 * has a living creatures, prevents people from passing 1790 * has a living creatures, prevents people from passing
1888 * through, etc) 1791 * through, etc)
1889 */ 1792 */
1890void 1793void
1891update_position (maptile *m, int x, int y) 1794mapspace::update_ ()
1892{ 1795{
1893 object *tmp, *last = 0; 1796 object *tmp, *last = 0;
1894 uint8 flags = 0, oldflags, light = 0, anywhere = 0; 1797 uint8 flags = 0, light = 0, anywhere = 0;
1895 New_Face *top, *floor, *middle; 1798 New_Face *top, *floor, *middle;
1896 object *top_obj, *floor_obj, *middle_obj; 1799 object *top_obj, *floor_obj, *middle_obj;
1897 MoveType move_block = 0, move_slow = 0, move_on = 0, move_off = 0, move_allow = 0; 1800 MoveType move_block = 0, move_slow = 0, move_on = 0, move_off = 0, move_allow = 0;
1898 1801
1899 oldflags = GET_MAP_FLAGS (m, x, y);
1900 if (!(oldflags & P_NEED_UPDATE))
1901 {
1902 LOG (llevDebug, "update_position called with P_NEED_UPDATE not set: %s (%d, %d)\n", m->path, x, y);
1903 return;
1904 }
1905
1906 middle = blank_face; 1802 middle = blank_face;
1907 top = blank_face; 1803 top = blank_face;
1908 floor = blank_face; 1804 floor = blank_face;
1909 1805
1910 middle_obj = 0; 1806 middle_obj = 0;
1911 top_obj = 0; 1807 top_obj = 0;
1912 floor_obj = 0; 1808 floor_obj = 0;
1913 1809
1914 for (tmp = GET_MAP_OB (m, x, y); tmp; last = tmp, tmp = tmp->above) 1810 for (tmp = bot; tmp; last = tmp, tmp = tmp->above)
1915 { 1811 {
1916 /* This could be made additive I guess (two lights better than 1812 /* This could be made additive I guess (two lights better than
1917 * one). But if so, it shouldn't be a simple additive - 2 1813 * one). But if so, it shouldn't be a simple additive - 2
1918 * light bulbs do not illuminate twice as far as once since 1814 * light bulbs do not illuminate twice as far as once since
1919 * it is a dissapation factor that is cubed. 1815 * it is a dissapation factor that is cubed.
1983 if (tmp->type == SAFE_GROUND) flags |= P_SAFE; 1879 if (tmp->type == SAFE_GROUND) flags |= P_SAFE;
1984 if (QUERY_FLAG (tmp, FLAG_ALIVE)) flags |= P_IS_ALIVE; 1880 if (QUERY_FLAG (tmp, FLAG_ALIVE)) flags |= P_IS_ALIVE;
1985 if (QUERY_FLAG (tmp, FLAG_DAMNED)) flags |= P_NO_CLERIC; 1881 if (QUERY_FLAG (tmp, FLAG_DAMNED)) flags |= P_NO_CLERIC;
1986 } 1882 }
1987 1883
1988 /* we don't want to rely on this function to have accurate flags, but 1884 this->light = light;
1989 * since we're already doing the work, we calculate them here.
1990 * if they don't match, logic is broken someplace.
1991 */
1992 if (((oldflags & ~(P_NEED_UPDATE | P_NO_ERROR)) != flags) && (!(oldflags & P_NO_ERROR)))
1993 LOG (llevDebug, "update_position: updated flags do not match old flags: %s (old=%d,new=%d) %x != %x\n",
1994 m->path, x, y, (oldflags & ~P_NEED_UPDATE), flags);
1995
1996 mapspace &s = m->at (x, y);
1997
1998 s.flags = flags; 1885 this->flags_ = flags;
1999 s.move_block = move_block & ~move_allow; 1886 this->move_block = move_block & ~move_allow;
2000 s.move_on = move_on; 1887 this->move_on = move_on;
2001 s.move_off = move_off; 1888 this->move_off = move_off;
2002 s.move_slow = move_slow; 1889 this->move_slow = move_slow;
2003 1890
2004 /* At this point, we have a floor face (if there is a floor), 1891 /* At this point, we have a floor face (if there is a floor),
2005 * and the floor is set - we are not going to touch it at 1892 * and the floor is set - we are not going to touch it at
2006 * this point. 1893 * this point.
2007 * middle contains the highest visibility face. 1894 * middle contains the highest visibility face.
2068 middle = blank_face; 1955 middle = blank_face;
2069 1956
2070 if (top == middle) 1957 if (top == middle)
2071 middle = blank_face; 1958 middle = blank_face;
2072 1959
2073 SET_MAP_FACE (m, x, y, top, 0); 1960 faces [0] = top; faces_obj [0] = top != blank_face ? top_obj : 0;
2074 if (top != blank_face) 1961 faces [1] = middle; faces_obj [1] = middle != blank_face ? middle_obj : 0;
2075 SET_MAP_FACE_OBJ (m, x, y, top_obj, 0); 1962 faces [2] = floor; faces_obj [2] = floor != blank_face ? floor_obj : 0;
2076 else
2077 SET_MAP_FACE_OBJ (m, x, y, NULL, 0);
2078
2079 SET_MAP_FACE (m, x, y, middle, 1);
2080 if (middle != blank_face)
2081 SET_MAP_FACE_OBJ (m, x, y, middle_obj, 1);
2082 else
2083 SET_MAP_FACE_OBJ (m, x, y, NULL, 1);
2084
2085 SET_MAP_FACE (m, x, y, floor, 2);
2086 if (floor != blank_face)
2087 SET_MAP_FACE_OBJ (m, x, y, floor_obj, 2);
2088 else
2089 SET_MAP_FACE_OBJ (m, x, y, NULL, 2);
2090
2091 SET_MAP_LIGHT (m, x, y, light);
2092} 1963}
2093
2094 1964
2095void 1965void
2096set_map_reset_time (maptile *map) 1966set_map_reset_time (maptile *map)
2097{ 1967{
2098 int timeout; 1968 int timeout = map->reset_timeout;
2099 1969
2100 timeout = MAP_RESET_TIMEOUT (map);
2101 if (timeout <= 0) 1970 if (timeout <= 0)
2102 timeout = MAP_DEFAULTRESET; 1971 timeout = MAP_DEFAULTRESET;
2103 if (timeout >= MAP_MAXRESET) 1972 if (timeout >= MAP_MAXRESET)
2104 timeout = MAP_MAXRESET; 1973 timeout = MAP_MAXRESET;
2105 MAP_WHEN_RESET (map) = time (0) + timeout; 1974
1975 map->reset_time = time (0) + timeout;
2106} 1976}
2107 1977
2108/* 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
2109 * 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
2110 * maps tile_map values if it tiles back to this one. It returns 1980 * maps tile_map values if it tiles back to this one. It returns
2138 * 2008 *
2139 */ 2009 */
2140int 2010int
2141out_of_map (maptile *m, int x, int y) 2011out_of_map (maptile *m, int x, int y)
2142{ 2012{
2143
2144 /* If we get passed a null map, this is obviously the 2013 /* If we get passed a null map, this is obviously the
2145 * case. This generally shouldn't happen, but if the 2014 * case. This generally shouldn't happen, but if the
2146 * map loads fail below, it could happen. 2015 * map loads fail below, it could happen.
2147 */ 2016 */
2148 if (!m) 2017 if (!m)
2150 2019
2151 if (x < 0) 2020 if (x < 0)
2152 { 2021 {
2153 if (!m->tile_path[3]) 2022 if (!m->tile_path[3])
2154 return 1; 2023 return 1;
2024
2155 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) 2025 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY)
2156 {
2157 load_and_link_tiled_map (m, 3); 2026 load_and_link_tiled_map (m, 3);
2158 } 2027
2159 return (out_of_map (m->tile_map[3], x + MAP_WIDTH (m->tile_map[3]), y)); 2028 return (out_of_map (m->tile_map[3], x + m->tile_map[3]->width, y));
2160 } 2029 }
2161 if (x >= MAP_WIDTH (m)) 2030
2031 if (x >= m->width)
2162 { 2032 {
2163 if (!m->tile_path[1]) 2033 if (!m->tile_path[1])
2164 return 1; 2034 return 1;
2035
2165 if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) 2036 if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY)
2166 {
2167 load_and_link_tiled_map (m, 1); 2037 load_and_link_tiled_map (m, 1);
2168 } 2038
2169 return (out_of_map (m->tile_map[1], x - MAP_WIDTH (m), y)); 2039 return (out_of_map (m->tile_map[1], x - m->width, y));
2170 } 2040 }
2041
2171 if (y < 0) 2042 if (y < 0)
2172 { 2043 {
2173 if (!m->tile_path[0]) 2044 if (!m->tile_path[0])
2174 return 1; 2045 return 1;
2046
2175 if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) 2047 if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY)
2176 {
2177 load_and_link_tiled_map (m, 0); 2048 load_and_link_tiled_map (m, 0);
2178 } 2049
2179 return (out_of_map (m->tile_map[0], x, y + MAP_HEIGHT (m->tile_map[0]))); 2050 return (out_of_map (m->tile_map[0], x, y + m->tile_map[0]->height));
2180 } 2051 }
2181 if (y >= MAP_HEIGHT (m)) 2052
2053 if (y >= m->height)
2182 { 2054 {
2183 if (!m->tile_path[2]) 2055 if (!m->tile_path[2])
2184 return 1; 2056 return 1;
2057
2185 if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) 2058 if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY)
2186 {
2187 load_and_link_tiled_map (m, 2); 2059 load_and_link_tiled_map (m, 2);
2188 } 2060
2189 return (out_of_map (m->tile_map[2], x, y - MAP_HEIGHT (m))); 2061 return (out_of_map (m->tile_map[2], x, y - m->height));
2190 } 2062 }
2191 2063
2192 /* Simple case - coordinates are within this local 2064 /* Simple case - coordinates are within this local
2193 * map. 2065 * map.
2194 */ 2066 */
2208{ 2080{
2209 2081
2210 if (*x < 0) 2082 if (*x < 0)
2211 { 2083 {
2212 if (!m->tile_path[3]) 2084 if (!m->tile_path[3])
2213 return NULL; 2085 return 0;
2214 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY) 2086 if (!m->tile_map[3] || m->tile_map[3]->in_memory != MAP_IN_MEMORY)
2215 load_and_link_tiled_map (m, 3); 2087 load_and_link_tiled_map (m, 3);
2216 2088
2217 *x += MAP_WIDTH (m->tile_map[3]); 2089 *x += m->tile_map[3]->width;
2218 return (get_map_from_coord (m->tile_map[3], x, y)); 2090 return (get_map_from_coord (m->tile_map[3], x, y));
2219 } 2091 }
2220 if (*x >= MAP_WIDTH (m)) 2092
2093 if (*x >= m->width)
2221 { 2094 {
2222 if (!m->tile_path[1]) 2095 if (!m->tile_path[1])
2223 return NULL; 2096 return 0;
2097
2224 if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY) 2098 if (!m->tile_map[1] || m->tile_map[1]->in_memory != MAP_IN_MEMORY)
2225 load_and_link_tiled_map (m, 1); 2099 load_and_link_tiled_map (m, 1);
2226 2100
2227 *x -= MAP_WIDTH (m); 2101 *x -= m->width;
2228 return (get_map_from_coord (m->tile_map[1], x, y)); 2102 return (get_map_from_coord (m->tile_map[1], x, y));
2229 } 2103 }
2104
2230 if (*y < 0) 2105 if (*y < 0)
2231 { 2106 {
2232 if (!m->tile_path[0]) 2107 if (!m->tile_path[0])
2233 return NULL; 2108 return 0;
2109
2234 if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY) 2110 if (!m->tile_map[0] || m->tile_map[0]->in_memory != MAP_IN_MEMORY)
2235 load_and_link_tiled_map (m, 0); 2111 load_and_link_tiled_map (m, 0);
2236 2112
2237 *y += MAP_HEIGHT (m->tile_map[0]); 2113 *y += m->tile_map[0]->height;
2238 return (get_map_from_coord (m->tile_map[0], x, y)); 2114 return (get_map_from_coord (m->tile_map[0], x, y));
2239 } 2115 }
2240 if (*y >= MAP_HEIGHT (m)) 2116
2117 if (*y >= m->height)
2241 { 2118 {
2242 if (!m->tile_path[2]) 2119 if (!m->tile_path[2])
2243 return NULL; 2120 return 0;
2121
2244 if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY) 2122 if (!m->tile_map[2] || m->tile_map[2]->in_memory != MAP_IN_MEMORY)
2245 load_and_link_tiled_map (m, 2); 2123 load_and_link_tiled_map (m, 2);
2246 2124
2247 *y -= MAP_HEIGHT (m); 2125 *y -= m->height;
2248 return (get_map_from_coord (m->tile_map[2], x, y)); 2126 return (get_map_from_coord (m->tile_map[2], x, y));
2249 } 2127 }
2250 2128
2251 /* Simple case - coordinates are within this local 2129 /* Simple case - coordinates are within this local
2252 * map. 2130 * map.
2272 2150
2273 } 2151 }
2274 else if (map1->tile_map[0] == map2) 2152 else if (map1->tile_map[0] == map2)
2275 { /* up */ 2153 { /* up */
2276 *dx = 0; 2154 *dx = 0;
2277 *dy = -MAP_HEIGHT (map2); 2155 *dy = -map2->height;
2278 } 2156 }
2279 else if (map1->tile_map[1] == map2) 2157 else if (map1->tile_map[1] == map2)
2280 { /* right */ 2158 { /* right */
2281 *dx = MAP_WIDTH (map1); 2159 *dx = map1->width;
2282 *dy = 0; 2160 *dy = 0;
2283 } 2161 }
2284 else if (map1->tile_map[2] == map2) 2162 else if (map1->tile_map[2] == map2)
2285 { /* down */ 2163 { /* down */
2286 *dx = 0; 2164 *dx = 0;
2287 *dy = MAP_HEIGHT (map1); 2165 *dy = map1->height;
2288 } 2166 }
2289 else if (map1->tile_map[3] == map2) 2167 else if (map1->tile_map[3] == map2)
2290 { /* left */ 2168 { /* left */
2291 *dx = -MAP_WIDTH (map2); 2169 *dx = -map2->width;
2292 *dy = 0; 2170 *dy = 0;
2293 2171
2294 } 2172 }
2295 else if (map1->tile_map[0] && map1->tile_map[0]->tile_map[1] == map2) 2173 else if (map1->tile_map[0] && map1->tile_map[0]->tile_map[1] == map2)
2296 { /* up right */ 2174 { /* up right */
2297 *dx = MAP_WIDTH (map1->tile_map[0]); 2175 *dx = map1->tile_map[0]->width;
2298 *dy = -MAP_HEIGHT (map1->tile_map[0]); 2176 *dy = -map1->tile_map[0]->height;
2299 } 2177 }
2300 else if (map1->tile_map[0] && map1->tile_map[0]->tile_map[3] == map2) 2178 else if (map1->tile_map[0] && map1->tile_map[0]->tile_map[3] == map2)
2301 { /* up left */ 2179 { /* up left */
2302 *dx = -MAP_WIDTH (map2); 2180 *dx = -map2->width;
2303 *dy = -MAP_HEIGHT (map1->tile_map[0]); 2181 *dy = -map1->tile_map[0]->height;
2304 } 2182 }
2305 else if (map1->tile_map[1] && map1->tile_map[1]->tile_map[0] == map2) 2183 else if (map1->tile_map[1] && map1->tile_map[1]->tile_map[0] == map2)
2306 { /* right up */ 2184 { /* right up */
2307 *dx = MAP_WIDTH (map1); 2185 *dx = map1->width;
2308 *dy = -MAP_HEIGHT (map2); 2186 *dy = -map2->height;
2309 } 2187 }
2310 else if (map1->tile_map[1] && map1->tile_map[1]->tile_map[2] == map2) 2188 else if (map1->tile_map[1] && map1->tile_map[1]->tile_map[2] == map2)
2311 { /* right down */ 2189 { /* right down */
2312 *dx = MAP_WIDTH (map1); 2190 *dx = map1->width;
2313 *dy = MAP_HEIGHT (map1->tile_map[1]); 2191 *dy = map1->tile_map[1]->height;
2314 } 2192 }
2315 else if (map1->tile_map[2] && map1->tile_map[2]->tile_map[1] == map2) 2193 else if (map1->tile_map[2] && map1->tile_map[2]->tile_map[1] == map2)
2316 { /* down right */ 2194 { /* down right */
2317 *dx = MAP_WIDTH (map1->tile_map[2]); 2195 *dx = map1->tile_map[2]->width;
2318 *dy = MAP_HEIGHT (map1); 2196 *dy = map1->height;
2319 } 2197 }
2320 else if (map1->tile_map[2] && map1->tile_map[2]->tile_map[3] == map2) 2198 else if (map1->tile_map[2] && map1->tile_map[2]->tile_map[3] == map2)
2321 { /* down left */ 2199 { /* down left */
2322 *dx = -MAP_WIDTH (map2); 2200 *dx = -map2->width;
2323 *dy = MAP_HEIGHT (map1); 2201 *dy = map1->height;
2324 } 2202 }
2325 else if (map1->tile_map[3] && map1->tile_map[3]->tile_map[0] == map2) 2203 else if (map1->tile_map[3] && map1->tile_map[3]->tile_map[0] == map2)
2326 { /* left up */ 2204 { /* left up */
2327 *dx = -MAP_WIDTH (map1->tile_map[3]); 2205 *dx = -map1->tile_map[3]->width;
2328 *dy = -MAP_HEIGHT (map2); 2206 *dy = -map2->height;
2329 } 2207 }
2330 else if (map1->tile_map[3] && map1->tile_map[3]->tile_map[2] == map2) 2208 else if (map1->tile_map[3] && map1->tile_map[3]->tile_map[2] == map2)
2331 { /* left down */ 2209 { /* left down */
2332 *dx = -MAP_WIDTH (map1->tile_map[3]); 2210 *dx = -map1->tile_map[3]->width;
2333 *dy = MAP_HEIGHT (map1->tile_map[3]); 2211 *dy = map1->tile_map[3]->height;
2334 2212
2335 } 2213 }
2336 else 2214 else
2337 { /* not "adjacent" enough */ 2215 { /* not "adjacent" enough */
2338 return 0; 2216 return 0;
2463{ 2341{
2464 int dx, dy; 2342 int dx, dy;
2465 2343
2466 return adjacent_map (op1->map, op2->map, &dx, &dy); 2344 return adjacent_map (op1->map, op2->map, &dx, &dy);
2467} 2345}
2346
2347object *
2348maptile::insert (object *op, int x, int y, object *originator, int flags)
2349{
2350 if (!op->flag [FLAG_REMOVED])
2351 op->remove ();
2352
2353 return insert_ob_in_map_at (op, this, originator, flags, x, y);
2354}
2355

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines