# Automap

## version 4 by Mark Tilford

Section 3 - Drawing the map - Writing to the character array

To place (ch - number) of (r - a room) at (x - a number) and (y - a number):
(- if ( {x} >= 0 && {x} < MAP_WIDTH && {y} >=0 && {y} < MAP_HEIGHT) {
Automap_Chars -> ( {y} * MAP_WIDTH + {x} ) = {ch};
Automap_links --> ( {y} * MAP_WIDTH + {x} ) = {r};
#endif;
}
-)

To place (ch - number) at (x - a number) and (y - a number):
(- if ( {x} >= 0 && {x} < MAP_WIDTH && {y} >=0 && {y} < MAP_HEIGHT) {
Automap_Chars -> ( {y} * MAP_WIDTH + {x} ) = {ch};
}
-)

To decide what number is the character at (sq - a number):
(- Automap_Chars -> {sq} -);

To decide what number is room size: if current zoom is map zoomed in, decide on 4; decide on 2.

[Map drawn room is a mappable room that varies. Map drawn direction is a direction that varies.]
Map drawn room is a room that varies. Map drawn direction is a direction that varies. [ Debugging variables ]

[Automap null room is a room. It is unmappable. ]

[ Draw Path ]
To draw a path from (room x - a number) and (room y - a number) to (dir - a direction) for (dist - a number) with (ch - a number):
[if ch is 76 begin; say "Drawing path with 76 from [map drawn room] to [map drawn direction]."; end if;]
[say "drawing path from ([room x], [room y]) to the [dir] with [ch]:[line break]";]
now dist is (dist - 1) times room size + 1;
let dx be the delta x of dir;
let dy be the delta y of dir;
let room x be room x + dx;
let room y be room y + dy;
while (room x >= 0 and room x < map width and room y >= 0 and room y < map height and dist > 0) begin;
let ch1 be ch;
let sq be (room y * map width) + room x;
let ch2 be the character at sq;
if ch2 is 32 or ch2 is ch begin; do nothing; [ Drawing over a space or a matching character is normal. ]
otherwise if ch2 is 90 or ch2 is 91; now ch1 is ch2; [ Drawing anything over an X or + is a nop. ]
otherwise if ch1 is 35 or ch1 is 36; now ch1 is 90; [ Drawing a ne/sw over nw/se or v.v makes an X. ]
[otherwise if ch1 is 35 or ch1 is 36; say "writing [ch] over [ch2] for X at ([room x], [room y])::[sq]."; now ch is 90;]
otherwise if ch1 is 1 or ch1 is 2; now ch1 is 91; [ Drawing a n/s over e/w or v.v makes a +.]
otherwise; say "Draw Path got value with [ch1] over [ch2] at ([room x], [room y]): BUG.";
end if;
if ch1 is not ch2, place ch1 at room x and room y;
now dist is dist - 1;
now room x is room x + dx;
now room y is room y + dy;
end while.

To decide what number is the maximum of (x - a number) and (y - a number): if (x < y), decide on y; decide on x.
To decide what number is the minimum of (x - a number) and (y - a number): if (x < y), decide on x; decide on y.

Include (-
[ ClearMap i;
!for (i = 0: i < MAP_WIDTH * MAP_HEIGHT: ++ i)
for (i = MAP_WIDTH * MAP_HEIGHT - 1; i >= 0; -- i)
Automap_Chars->i = 32; ! Empty cell
if (Automap_links ~= 0)
for (i = MAP_WIDTH * MAP_HEIGHT - 1; i >= 0; -- i)
Automap_links-->i = 0; ! No room
#endif;
]; -);

To clear the map: (- ClearMap(); -);

[ Draw Map ]
To decide whether the map is drawn:
if current zoom is map absent, decide no;
if location is a mappable room begin;
[start capturing text;]
[say "location is a mappable room.";]
begin the automap work activity;
begin the automap drawing activity;
let max_x be the map_x of location;
let max_y be the map_y of location;
repeat with loop_room running through the mappable rooms coregional with location begin;
if the map_x of loop_room is greater than max_x, now max_x is the map_x of loop_room;
if the map_y of loop_room is greater than max_y, now max_y is the map_y of loop_room;
end repeat;
let map_min_x be 0;
[ If the width of the drawn map is no more than the width allocated, center the map horizontally.]
[ Otherwise, place the map so as to center the location, unless that would go over the edge ]
[ max (wmost, min (center - WIDTH/2, emost - WIDTH)) ]
[let n1 be 2 + (room size) * (1 + max_x);]
[say "[2 + (room size) * (1 + max_x)] ?>= [map width] :: [2 + (1 + the map_x of location) * (room size) - map width / 2] [(1 + max_x) * room size - map width].";]
[say "Would center x at [((room size * (1 + max_x)) - map width) / 2] == ([room size] * [1 + max_x] - [map width]) / 2.";
if 2 + (room size) * (1 + max_x) >= map width begin;
[now map_min_x is the maximum of -2 and (the minimum of (2 + (1 + the map_x of location) * (room size) - map width / 2) and ((1 + max_x) * room size - map width));] [ I have no idea why the parens cause this line to fail.]
now map_min_x is the maximum of -2 and (the minimum of (2 + (1 + the map_x of location) * (room size) - map width / 2) and (1 + max_x) * room size - map width);
otherwise;
now map_min_x is (room size * (1 + max_x) - map width) / 2;
end if;]
if 1 is 1 begin;
[say "room size = [room size], map width = [map width], max_x = [max_x], map_x = [ map_x of location ], ";]
let shown_map_width be (room size) * (1 + max_x); increase shown_map_width by 1;
[say "shown_map_width is [shown_map_width], ";]
[let shown_map_start be shown_map_width - map width;]
let center_location_start be (1 + the map_x of location) * room size; decrease center_location_start by 1; [ x coordinate of location ]
[say "center location start is [center_location_start] ";]
decrease center_location_start by room size / 2;
[say " to [center_location_start], ";]
[decrease center_location_start by map height / 2;]
[decrease center_location_start by map width;
now center_location_start is center_location_start / 2; [ x coordinate of start position that would center location ]]
decrease center_location_start by (map width / 2);
[say " to [center_location_start], ";]
let eastmost_start be (1 + max_x) * room size; increase eastmost_start by 0; [ x coordinate of eastmost point ]
now eastmost_start is eastmost_start - map width; [ x coordinate of start position that would be eastmost point at the edge ]
[say "eastmost_start is [ eastmost_start ], ";]
if shown_map_width > map width begin;
[increase center_location_start by 2;]
now map_min_x is the minimum of center_location_start and eastmost_start;
now map_min_x is the maximum of -1 and map_min_x;
otherwise;
[[now map_min_x is center_location_start;]
[now map_min_x is shown_map_width;
decrease map_min_x by ( map width / 2);]]
now map_min_x is shown_map_width - map width;
decrease map_min_x by 2;
now map_min_x is map_min_x / 2;
[decrease map_min_x by 1;] [compensate that (0,0) is a corner of a cell, not the center]
end if;
[say "map_min_x is [map_min_x].";]
[say "room size = [room size], map width = [map width], max_x = [max_x], map_x = [ map_x of location ], shown_map_width is [shown_map_width], center location start is [center_location_start], eastmost_start is [ eastmost_start ], map_min_x is [map_min_x].";]
end if;
let map_min_y be 0;
[ If the width of the drawn map is no more than the width allocated, center the map horizontally.]
[ Otherwise, place the map so as to center the location, unless that would go over the edge ]
[ max (nmost, min (center - WIDTH/2, smost - WIDTH)) ]
[if 2 + (room size) * (1 + max_y) >= map height begin;
now map_min_y is the maximum of -2 and (the minimum of (2 + (1 + the map_y of location) * (room size) - map height / 2) and (1 + max_y) * room size - map height);
otherwise;
now map_min_y is (room size * (1 + max_y) - map height) / 2;
end if;]
if 1 is 1 begin; [ limiting the scope of the local variables ]
[say "room size = [room size], map_height = [map height], max_y = [max_y], map_y = [ map_y of location ], ";]
let shown_map_height be (room size) * (1 + max_y); increase shown_map_height by 1;
[say "shown_map_height is [shown_map_height], ";]
let center_location_start be (1 + map_y of location) * room size; decrease center_location_start by 1; [ y coordinate of location ]
decrease center_location_start by room size / 2;
[say "center location start is [center_location_start] ";]
decrease center_location_start by map height / 2; [say "to [center_location_start], ";]
let southmost_start be (1 + max_y) * room size; increase southmost_start by 0; [ y coordinate of southmost point ]
decrease southmost_start by map height; [ y coordinate of start position that would be southmost point at the edge ]
[say "southmost_start is [ southmost_start ], ";]
if shown_map_height > map height begin;
[decrease center_location_start by 2;]
now map_min_y is the minimum of center_location_start and southmost_start;
[decrease map_min_y by (map height minus 1) / 2;]
now map_min_y is the maximum of -1 and map_min_y;
otherwise;
now map_min_y is shown_map_height - map height;
decrease map_min_y by 2;
now map_min_y is map_min_y / 2;
[decrease map_min_y by 1;] [compensate that (0,0) is a corner of a cell, not the center]
end if;
[say "map_min_y is [map_min_y].";]
end if;
Clear the map;
[reset 76;]
repeat with loop_room running through the mappable rooms coregional with location begin;
now map drawn room is loop_room;
let temp_x be (the map_x of loop_room * room size) - map_min_x;
let temp_y be (the map_y of loop_room * room size) - map_min_y;
[say "Gridding [loop_room] at [temp_x], [temp_y]";]
[if (temp_x + room size >= 0) and (temp_x < map width) and (temp_y + room size >= 0) and (temp_y < map height), begin;]
[say "[temp_x + room size] >= 0 && [temp_x] < [map width] && [temp_y + room size] >= 0 && [temp_y] < [map height].";]
if (temp_x + room size >= 0) and (temp_x < map width) and (temp_y + room size >= 0) and (temp_y < map height) begin;
if the current zoom is map zoomed in begin;
let offset be 0;
if loop_room is location, now offset is 17; [ Difference between empty image chars and full image chars ]
[check 76;]
now map drawn direction is southwest;
if loop_room has an exit to southwest begin;
place sw exit + offset of loop_room at temp_x and temp_y + 2;
[draw a path from temp_x and temp_y + 2 to -1 and 1 for (the distance from loop_room to the southwest) with ne sw path;]
draw a path from temp_x and temp_y + 2 to southwest for the distance southwest from loop_room with ne sw path;
otherwise;
place sw corner + offset of loop_room at temp_x and temp_y + 2;
end if;
[check 76;]
now map drawn direction is northwest;
if loop_room has an exit to northwest begin;
place nw exit + offset of loop_room at temp_x and temp_y;
draw a path from temp_x and temp_y to northwest for the distance northwest from loop_room with nw se path;
otherwise;
place nw corner + offset of loop_room at temp_x and temp_y;
end if;
[check 76;]
now map drawn direction is northeast;
if loop_room has an exit to northeast begin;
place ne exit + offset of loop_room at temp_x + 2 and temp_y;
draw a path from temp_x + 2 and temp_y to northeast for the distance northeast from loop_room with ne sw path;
otherwise;
place ne corner + offset of loop_room at temp_x + 2 and temp_y;
end if;
[check 76;]
now map drawn direction is southeast;
if loop_room has an exit to southeast begin;
place se exit + offset of loop_room at temp_x + 2 and temp_y + 2;
draw a path from temp_x + 2 and temp_y + 2 to southeast for the distance southeast from loop_room with nw se path;
otherwise;
place se corner + offset of loop_room at temp_x + 2 and temp_y + 2;
end if;
[check 76;]
now map drawn direction is south;
if loop_room has an exit to south begin;
place south exit + offset of loop_room at temp_x + 1 and temp_y + 2;
draw a path from temp_x + 1 and temp_y + 2 to south for the distance south from loop_room with north south path;
otherwise;
place south wall + offset of loop_room at temp_x + 1 and temp_y + 2;
end if;
[check 76;]
now map drawn direction is north;
if loop_room has an exit to north begin;
place north exit + offset of loop_room at temp_x + 1 and temp_y;
draw a path from temp_x + 1 and temp_y to north for the distance north from loop_room with north south path;
otherwise;
place north wall + offset of loop_room at temp_x + 1 and temp_y;
end if;
[check 76;]
now map drawn direction is west;
if loop_room has an exit to west begin;
place west exit + offset of loop_room at temp_x and temp_y + 1;
draw a path from temp_x and temp_y + 1 to west for the distance west from loop_room with east west path;
otherwise;
place west wall + offset of loop_room at temp_x and temp_y + 1;
end if;
[check 76;]
now map drawn direction is east;
if loop_room has an exit to east begin;
place east exit + offset of loop_room at temp_x + 2 and temp_y + 1;
draw a path from temp_x + 2 and temp_y + 1 to east for the distance east from loop_room with east west path;
otherwise;
place east wall + offset of loop_room at temp_x + 2 and temp_y + 1;
end if;
[check 76;]
now map drawn direction is up;
[ Now, draw the central square of the room and, if needed, and up / down / questionmark arrow within ]
place 37 + offset of loop_room at temp_x + 1 and temp_y + 1;
now offset is 0;
if loop_room is location, now offset is 31; [ changes up arrow to full up arrow and the like ]
if loop_room has an exit to up and loop_room has an exit to down begin;
place up down arrow + offset of loop_room at temp_x + 1 and temp_y + 1;
otherwise if loop_room has an exit to up;
place up arrow + offset of loop_room at temp_x + 1 and temp_y + 1;
otherwise if loop_room has an exit to down;
place down arrow + offset of loop_room at temp_x + 1 and temp_y + 1;
[otherwise if loop_room has an exit to inside or loop_room has an exit to outside;
if loop_room is location begin;
place full question arrow at temp_x + 1 and temp_y + 1;
otherwise;
place question arrow at temp_x + 1 and temp_y + 1;
end if;]
otherwise if loop_room has an exit to inside or loop_room has an exit to outside;
let ch be automap in;
if loop_room is location begin;
if loop_room has an exit to inside and loop_room has an exit to outside begin;
now ch is automap present inout;
otherwise if loop_room has an exit to inside;
now ch is automap present in;
otherwise;
now ch is automap present out;
end if;
otherwise;
if loop_room has an exit to inside and loop_room has an exit to outside begin;
now ch is automap inout;
otherwise if loop_room has an exit to inside;
now ch is automap in;
otherwise;
now ch is automap out;
end if;
end if;
place ch of loop_room at temp_x + 1 and temp_y + 1;
end if;
[check 76;]
otherwise; [ in zoomed out mode ]
if loop_room has an exit to southwest, draw a path from temp_x and temp_y to southwest for the distance southwest from loop_room with ne sw path;
if loop_room has an exit to northwest, draw a path from temp_x and temp_y to northwest for the distance northwest from loop_room with nw se path;
if loop_room has an exit to southeast, draw a path from temp_x and temp_y to southeast for the distance southeast from loop_room with nw se path;
if loop_room has an exit to northeast, draw a path from temp_x and temp_y to northeast for the distance northeast from loop_room with ne sw path;
if loop_room has an exit to south, draw a path from temp_x and temp_y to south for the distance south from loop_room with north south path;
if loop_room has an exit to north, draw a path from temp_x and temp_y to north for the distance north from loop_room with north south path;
if loop_room has an exit to east, draw a path from temp_x and temp_y to east for the distance east from loop_room with east west path;
if loop_room has an exit to west, draw a path from temp_x and temp_y to west for the distance west from loop_room with east west path;
let offset be 0;
if loop_room is location, now offset is 31;
if loop_room has an exit to up and loop_room has an exit to down begin;
place up down arrow + offset of loop_room at temp_x and temp_y;
otherwise if loop_room has an exit to up;
place up arrow + offset of loop_room at temp_x and temp_y;
otherwise if loop_room has an exit to down;
place down arrow + offset of loop_room at temp_x and temp_y;
otherwise if loop_room has an exit to inside or loop_room has an exit to outside;
[if loop_room is location begin;
place full question arrow at temp_x and temp_y;
otherwise;
place question arrow at temp_x and temp_y;
end if;]
let ch be automap in;
if loop_room is location begin;
if loop_room has an exit to inside and loop_room has an exit to outside begin;
now ch is automap present inout;
otherwise if loop_room has an exit to inside;
now ch is automap present in;
otherwise;
now ch is automap present out;
end if;
otherwise;
if loop_room has an exit to inside and loop_room has an exit to outside begin;
now ch is automap inout;
otherwise if loop_room has an exit to inside;
now ch is automap in;
otherwise;
now ch is automap out;
end if;
end if;
place ch of loop_room at temp_x and temp_y;
otherwise if loop_room is location;
place full room of loop_room at temp_x and temp_y;
otherwise;
place empty room of loop_room at temp_x and temp_y;
end if;
end if;
[now map drawn room is nothing;]
[now map drawn room is automap null room;]
end if;
end repeat;
end the automap drawing activity;
end the automap work activity;
[stop capturing text;]
decide yes;
end if;
[stop capturing text;]
decide no.