home · contact · privacy
Fixed bug that led to endless loop in nearest_enemy_dir().
[plomrogue] / src / map.c
1 #include "map.h"
2 #include <stdint.h>      /* for uint8_t, uint16_t, uint32_t */
3 #include "misc.h"        /* for try_malloc(), center_offset(), rrand() */
4 #include "map_objects.h" /* for get_player() */
5 #include "yx_uint16.h"   /* for yx_uint16, dir enums */
6 #include "windows.h"     /* for struct Win */
7 #include "main.h"        /* for world global */
8 #include "wincontrol.h"  /* for get_win_by_id() */
9
10
11
12 extern struct Map init_map()
13 {
14     char * f_name = "init_map()";
15     struct Map map;
16     map.size.x = 64;
17     map.size.y = 64;
18     uint32_t size = map.size.x * map.size.y;
19     map.cells = try_malloc(size, f_name);
20     uint16_t y, x;
21     for (y = 0; y < map.size.y; y++)
22     {
23         for (x = 0; x < map.size.x; map.cells[(y * map.size.x) + x] = '~', x++);
24     }
25     map.cells[size / 2 + (map.size.x / 2)] = '.';
26     uint32_t curpos;
27     while (1)
28     {
29         y = rrand() % map.size.y;
30         x = rrand() % map.size.x;
31         curpos = y * map.size.x + x;
32         if ('~' == map.cells[curpos]
33             && ((curpos >= map.size.x && '.' == map.cells[curpos - map.size.x])
34                 || (curpos < map.size.x * (map.size.y-1)
35                      && '.' == map.cells[curpos + map.size.x])
36                 || (curpos > 0 && curpos % map.size.x != 0
37                     && '.' == map.cells[curpos-1])
38                 || (curpos < (map.size.x * map.size.y)
39                     && (curpos+1) % map.size.x != 0
40                     && '.' == map.cells[curpos+1])))
41         {
42             if (y == 0 || y == map.size.y - 1 || x == 0 || x == map.size.x - 1)
43             {
44                 break;
45             }
46             map.cells[y * map.size.x + x] = '.';
47         }
48     }
49     return map;
50 }
51
52
53
54 extern void map_scroll(char d)
55 {
56     struct Win * win = get_win_by_id('m');
57     uint16_t offset;
58     if (('N' == d || 'S' == d) && world.map->size.y > win->framesize.y)
59     {
60         offset = center_offset(win->center.y,
61                                world.map->size.y, win->framesize.y);
62         win->center.y = offset + (win->framesize.y / 2);
63         if ('S' == d && win->center.y < world.map->size.y - 1)
64         {
65             win->center.y++;
66             return;
67         }
68         win->center.y = win->center.y - ('N' == d && win->center.y > 0);
69     }
70     else if (('W' == d || 'E' == d) && world.map->size.x > win->framesize.x)
71     {
72         offset = center_offset(win->center.x,
73                                world.map->size.x, win->framesize.x);
74         win->center.x = offset + (win->framesize.x / 2);
75         if ('E' == d && win->center.x < world.map->size.x - 1)
76         {
77             win->center.x++;
78             return;
79         }
80         win->center.x = win->center.x - ('W' == d && win->center.x > 0);
81     }
82 }
83
84
85
86 extern void map_center()
87 {
88     struct MapObj * player = get_player();
89     struct Win * win_map   = get_win_by_id('m');
90     win_map->center = player->pos;
91 }
92
93
94
95 extern uint8_t is_passable(struct Map * map, struct yx_uint16 pos)
96 {
97     uint8_t passable = 0;
98     if (0 <= pos.x && pos.x < map->size.x && 0 <= pos.y && pos.y < map->size.y)
99     {
100         passable = (('.' == map->cells[pos.y * map->size.x + pos.x]));
101     }
102     return passable;
103 }