-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathModified Automap.i7x
1242 lines (1048 loc) · 56.2 KB
/
Modified Automap.i7x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Version 4 of Modified Automap by Mark Tilford begins here.
"An extension to automatically draw a map."
Section 1 - Global constants, Memory management, Kinds, and verbs
Use automap manual exploration translates as (- Constant AUTOMAP_MANUAL_EXPLORATION 1; -).
Use automap manual display translates as (- Constant AUTOMAP_MANUAL_DISPLAY 1; -).
Use automap visible background translates as (- Constant AUTOMAP_VISIBLE_BACKGROUND 1; -).
Use automap hide paths through closed doors translates as (- Constant AUTOMAP_HIDE_CLOSED_DOORS 1; -).
Use automap reserved area of at least 400 translates as (- Constant USEOP_MAP_ALLOC_AREA {N}; -).
Use automap static allocation translates as (- Constant AUTOMAP_ALLOCATE_STATIC 1; -).
Use automap hyperlinks translates as (- Constant AUTOMAP_HYPERLINKS 1; -).
[Use automap draw debug variables translates as (- Constant AUTOMAP_DRAW_DEBUG_VARIABLES 1; -).]
[Include Text Capture by Eric Eve.
Use maximum capture buffer length of at least 512.]
Include (-
Constant AUTOMAP_CHAR_IN 3;
Constant AUTOMAP_CHAR_OUT 4;
Constant AUTOMAP_CHAR_INOUT 5;
Constant AUTOMAP_CHAR_PRESENT_IN 6;
Constant AUTOMAP_CHAR_PRESENT_OUT 7;
Constant AUTOMAP_CHAR_PRESENT_INOUT 8;
Constant AUTOMAP_CHAR_DARK 9;
Constant AUTOMAP_CHAR_PRESENT_DARK 10;
#ifdef TARGET_ZCODE;
#ifndef AUTOMAP_ALLOCATE_STATIC;
Constant AUTOMAP_ALLOCATE_STATIC 1;
#endif;
#endif;
#ifdef AUTOMAP_ALLOCATE_STATIC;
Constant MAP_ALLOC_AREA USEOP_MAP_ALLOC_AREA;
Array Automap_Chars -> MAP_ALLOC_AREA;
#ifdef AUTOMAP_HYPERLINKS;
Global Automap_links --> MAP_ALLOC_AREA;
#endif;
#ifnot;
Global MAP_ALLOC_AREA = 0;
Global Automap_Chars = 0;
Global printed_nomalloc_message = 0;
#ifdef AUTOMAP_HYPERLINKS;
Global Automap_links = 0;
#endif;
#endif;
Global MAP_WIDTH = 0;
Global MAP_HEIGHT = 0;
[ Reserve_Map_Memory rows cols link_memory;
if (rows == 0) {
rows = 0;
cols = 0;
return;
}
if (rows * cols > MAP_ALLOC_AREA) {
!#ifdef TARGET_ZCODE;
#ifdef AUTOMAP_ALLOCATE_STATIC;
if (rows > MAP_ALLOC_AREA) {
MAP_WIDTH = 0;
MAP_HEIGHT = 0;
return;
}
MAP_HEIGHT = rows;
MAP_WIDTH = MAP_ALLOC_AREA / rows;
return;
#ifnot;
if (~~check_for_malloc()) {
if ( (+ current zoom +) == (+ map absent +) )
return;
if (~~Printed_nomalloc_message) {
print "[Your interpreter does not support dynamic memory allocation. Automap features will not function.]^";
Printed_nomalloc_message = true;
}
(+ current zoom +) = (+ map absent +);
return;
}
printed_nomalloc_message = false;
if (Automap_Chars ~= 0) {
@mfree Automap_Chars;
Automap_Chars = 0;
}
MAP_ALLOC_AREA = rows * cols;
@malloc MAP_ALLOC_AREA Automap_Chars;
if (Automap_Chars == 0) {
MAP_ALLOC_AREA = 0;
MAP_WIDTH = 0;
MAP_HEIGHT = 0;
rfalse;
}
#ifdef AUTOMAP_HYPERLINKS;
if (Automap_Links ~= 0) {
@mfree Automap_links;
Automap_Links = 0;
}
link_memory = MAP_ALLOC_AREA * WORDSIZE;
@malloc link_memory Automap_links;
#endif;
#endif;
}
MAP_WIDTH = cols;
MAP_HEIGHT = rows;
];
[ Check_for_malloc rv;
#ifndef AUTOMAP_ALLOCATE_STATIC;
@gestalt 7 0 rv;
return rv;
#ifnot;
return 1;
#endif;
];
!#Endif;
-) after "Definitions.i6t".
To decide whether there is no dynamic allocation conflict:
(- Check_for_malloc() -).
To reserve automap memory of (rows - a number) rows by (cols - a number) cols/columns : (- Reserve_Map_Memory ({rows}, {cols}) ;-).
To reserve automap memory of (cols - a number) cols/columns by (rows - a number) rows: (- Reserve_Map_Memory ({rows}, {cols}) ;-).
To reserve automap memory of (rows - a number) by (cols - a number): (- Reserve_Map_Memory ({rows}, {cols}) ;-).
To reserve automap memory of (rows - a number) rows: (- Reserve_Map_Memory ({rows}, VM_ScreenWidth()-2); -).
Include Basic Screen Effects by Emily Short.
[A Mappable Room is a kind of room.
A mappable room has a number called map_x.
A mappable room has a number called map_y.
A mappable room can be currently_mapped. A mappable room is usually not currently_mapped.]
A room can be mappable or unmappable. A room is usually mappable.
A room has a number called map_x. A room has a number called map_y.
A room can be currently_mapped. A room is usually not currently_mapped.
To decide what number is the distance (d - a direction) from (r - a room): decide on 1.
[Coregionality relates mappable rooms to each other in groups. The verb to be coregional with implies the coregionality relation.]
Coregionality relates rooms to each other in groups. The verb to be coregional with implies the coregionality relation.
Map zoomedness is a kind of value. The Map zoomednesses are map zoomed out, map zoomed in, and map absent.
Current zoom is a map zoomedness that varies. [The current zoom is map zoomed in.] [The current zoom is map absent.]
To report dynamic allocation conflict:
say "[bracket]Your interpreter does not support dynamic allocation, so the automap will not function.[close bracket][line break]";
now current zoom is map absent;
Zooming in is an action out of world applying to nothing. Understand "zoom in" as zooming in.
Carry out zooming in: if there is no dynamic allocation conflict begin; say "Zooming in!"; now current zoom is map zoomed in; otherwise; report dynamic allocation conflict; end if.
Zooming out is an action out of world applying to nothing. Understand "zoom out" as zooming out.
Carry out zooming out:
if there is no dynamic allocation conflict begin; say "Zooming out!"; now current zoom is map zoomed out; otherwise; report dynamic allocation conflict; end if.
Zooming away is an action out of world applying to nothing. Understand "zoom away" as zooming away. Carry out zooming away: say "Removing map."; now current zoom is map absent.
ZoomingMisc is an action out of world applying to nothing. Understand "zoom" as zoomingmisc.
Carry out zoomingmisc:
if there is no dynamic allocation conflict begin;
if current zoom is map zoomed in begin;
try zooming out;
otherwise if current zoom is map zoomed out;
try zooming away;
otherwise;
try zooming in;
end if;
otherwise;
report dynamic allocation conflict;
end if.
Map displayness is a kind of value. The map displaynesses are map display ascii, map display automatic, map display fancy, map display unicode. Current displayness is a map displayness that varies.
Map displaying unicode is an action out of world applying to nothing. Understand "map unicode" as map displaying unicode. Carry out map displaying unicode: now current displayness is map display unicode; say "Displaying map with unicode character set.".
Map displaying fancy is an action out of world applying to nothing. Understand "map fancy" as map displaying fancy. Understand "map font 3" as map displaying fancy. Understand "map beyond zork" as map displaying fancy. Carry out map displaying fancy: now current displayness is map display fancy; say "Displaying map with fancy character set.".
Map displaying ascii is an action out of world applying to nothing. Understand "map simple/ascii/plain" as map displaying ascii. Carry out map displaying ascii: now current displayness is map display ascii; say "Displaying map with simple character set.".
Gargoyle workaround is an action out of world applying to nothing. Understand "gargoyle bug workaround" as gargoyle workaround. Carry out gargoyle workaround: now current displayness is map display ascii; say "Activating workaround for buggy interpreter.".
Map displaying automatic is an action out of world applying to nothing. Understand "map auto" as map displaying automatic. Carry out map displaying automatic: now current displayness is map display automatic; say "Displaying map with automatic character set."
Automap work is an activity. ["Catchall activity in case the author wants to do something different while doing automap related activity."]
Automap exploring is an activity. ["Check a room, and join all adjacent rooms which are currently_mapped to its automap region."]
Automap drawing is an activity. ["writing the array that shows the automap."]
To decide whether (dir - a direction) is region preserving:
if dir is north or dir is east or dir is west or dir is south or dir is northeast or dir is southeast or dir is northwest or dir is southwest, decide yes;
if dir is up or dir is down or dir is inside or dir is outside, decide no;
say "Error: Bad direction [dir]!"; decide no.
To decide what number is the delta x of (dir - a direction):
if dir is west or dir is northwest or dir is southwest, decide on -1;
if dir is east or dir is northeast or dir is southeast, decide on 1;
decide on 0.
To decide what number is the delta y of (dir - a direction):
if dir is north or dir is northwest or dir is northeast, decide on -1;
if dir is south or dir is southwest or dir is southeast, decide on 1;
decide on 0.
[Understand north south path as 40.]
To decide what number is automap in: decide on 3.
To decide what number is automap out: decide on 4.
To decide what number is automap inout: decide on 5.
To decide what number is automap present in: decide on 6.
To decide what number is automap present out: decide on 7.
To decide what number is automap present inout: decide on 8.
To decide what number is automap dark: decide on 9.
To decide what number is automap present dark: decide on 10.
To decide what number is north south path: decide on 2.
To decide what number is east west path: decide on 1.
To decide what number is ne sw path: decide on 35.
To decide what number is nw se path: decide on 36.
To decide what number is diagonal cross: decide on 90.
To decide what number is orthogonal cross: decide on 91.
To decide what number is south wall: decide on 38.
To decide what number is north wall: decide on 39.
To decide what number is east wall: decide on 40.
To decide what number is west wall: decide on 41.
To decide what number is north exit: decide on 42.
To decide what number is south exit: decide on 43.
To decide what number is east exit: decide on 44.
To decide what number is west exit: decide on 45.
To decide what number is sw corner: decide on 46.
To decide what number is nw corner: decide on 47.
To decide what number is ne corner: decide on 48.
To decide what number is se corner: decide on 49.
To decide what number is sw exit: decide on 50.
To decide what number is nw exit: decide on 51.
To decide what number is ne exit: decide on 52.
To decide what number is se exit: decide on 53.
To decide what number is up arrow: decide on 92.
To decide what number is down arrow: decide on 93.
To decide what number is up down arrow: decide on 94.
To decide what number is question arrow: decide on 96.
To decide what number is empty cell: decide on 32.
To decide what number is full room: decide on 54.
To decide what number is empty room: decide on 95.
To decide what number is full south wall: decide on 55.
To decide what number is full north wall: decide on 56.
To decide what number is full east wall: decide on 57.
To decide what number is full west wall: decide on 58.
To decide what number is full north exit: decide on 59.
To decide what number is full south exit: decide on 60.
To decide what number is full east exit: decide on 61.
To decide what number is full west exit: decide on 62.
To decide what number is full sw corner: decide on 63.
To decide what number is full nw corner: decide on 64.
To decide what number is full ne corner: decide on 65.
To decide what number is full se corner: decide on 66.
To decide what number is full sw exit: decide on 67.
To decide what number is full nw exit: decide on 68.
To decide what number is full ne exit: decide on 69.
To decide what number is full se exit: decide on 70.
To decide what number is full up arrow: decide on 123.
To decide what number is full down arrow: decide on 124.
To decide what number is full up down arrow: decide on 125.
To decide what number is full question arrow: decide on 126.
To decide what number is map width:
(- MAP_WIDTH -);
To decide what number is map height:
(- MAP_HEIGHT -);
Section 2 - Exploration - determining how rooms should be placed relative to each other
[ Unmap Room ]
To unmap (r - a room):
now r is not coregional with r;
now r is not currently_mapped.
To remap/explore (r - a room):
unless r is explored, say "Error exploring [r] - BUG.";
[ Explore Room ]
To decide whether (r - a room) is explored:
[say "Exploring [r].";]
begin the automap work activity;
begin the automap exploring activity;
if r is a mappable room
begin;
if r is not currently_mapped begin;
[say "Setting [r] to currently_mapped.";]
now map_x of r is 0;
now map_y of r is 0;
now r is currently_mapped;
end if;
[say "mapped_room is [mapped_room].";]
repeat with dir running through directions
begin;
if dir is region preserving and r has an exit to the dir
begin;
let next_room be the room dir from the r;
[say "[mapped_room] : [dir] : [next_room].";]
if next_room is a mappable room
begin;
[if next_room is placed 1 and 1 from r, say "Huh.";]
let d be the distance dir from r;
let ddx be d times (the delta x of dir);
let ddy be d times (the delta y of dir);
unless next_room is placed ddx and ddy from r, say "Error exploring [dir] from [r].";
end if;
end if;
end repeat;
end if;
end the automap exploring activity;
end the automap work activity;
decide yes.
[ Recenter Region : Recoordinate the rooms in a region so that the minimum x and the minimum y of the region are 0. ]
To recenter the region of (r - a mappable room):
let min_x be the map_x of r;
let min_y be the map_y of r;
repeat with loop_room running through all mappable rooms coregional with r begin;
if the map_x of loop_room is less than min_x, now min_x is the map_x of loop_room;
if the map_y of loop_room is less than min_y, now min_y is the map_y of loop_room;
end repeat;
repeat with loop_room running through all mappable rooms coregional with r begin;
now the map_x of loop_room is the map_x of loop_room - min_x;
now the map_y of loop_room is the map_y of loop_room - min_y;
end repeat.
[ Join Regions : decide whether (nr - mappable room) is placed (dx - a number) and (dy - a number) from (or - mappable room):]
To decide whether (new room - mappable room) is placed (dx - a number) and (dy - a number) from (old room - mappable room):
[ If the either room isn't currently_mapped, do nothing. ]
if new room is not currently_mapped or old room is not currently_mapped, decide yes;
[say "Trying to place [new room] at ([dx], [dy]) relative to [old room].";]
[say "Normal decision.";]
[now old room is currently_mapped;]
[ if they're in the same region, check whether the placements are consistent. ]
if new room is coregional with old room begin;
[say "The coregional test.";]
if map_x of new room is map_x of old room plus dx and map_y of new room is map_y of old room plus dy, decide yes;
decide no;
end if;
[ otherwise, join the two regions ]
let delta_x be (map_x of old room) + dx - (map_x of new room);
let delta_y be (map_y of old room) + dy - (map_y of new room);
repeat with loop_room running through all mappable rooms coregional with new room
begin;
now map_x of loop_room is (map_x of loop_room) + (delta_x);
now map_y of loop_room is map_y of loop_room + delta_y;
end repeat;
now old room is coregional with new room;
recenter the region of old room;
decide yes.
To decide whether (r - a room) is not explored:
if r is explored, decide no; decide yes.
To decide whether (r - a room) has an exit to the/-- (d - a direction):
if the automap hide paths through closed doors option is not active and the room-or-door d from r is a closed door, decide no;
If the room d from r is a room, decide yes; decide no.
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};
#ifdef AUTOMAP_HYPERLINKS;
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
#ifdef AUTOMAP_HYPERLINKS;
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.
Section 4 - Displaying the map
[ Adapted from Emily Short's Basic Screen Effects ]
To fill status bar with (selected table - a table-name) and map:
let __n be the number of rows in the selected table;
if the current zoom is map absent begin;
deepen status line to __n rows;
otherwise;
deepen status line to __n + map height rows;
end if;
let __index be 1;
repeat through selected table
begin;
move cursor to __index;
say "[left entry]";
center central entry at row __index;
right align cursor to __index;
say "[right entry]";
now __index is __index + 1;
end repeat;
if the map is drawn and the current zoom is not map absent, display the map at line __n;
[if __b and the current zoom is not map absent, display the map at line __n + 1;]
Before constructing the status line (this is the automap add adjacent rooms to map rule) : if the automap manual exploration option is not active and the location is a mappable room and the location is not explored, say "Error exploring [location]."
Table of Lamdil Status
left central right
"[location]" "Level: [level of the player]" "Dodge: %"
"[left hand status line]" "HP: [current hit points of the player]/[maximum hit points of the player]" "Parry: % "
"[right hand status line]" "Damage Reduction: [damageReduction of the player]" "Block: % "
"" "[time of day]" ""
Rule for constructing the status line (this is the automap standard status line rule):
fill status bar with table of lamdil status and map.
To display the map at line (n - a number):
(- I6_Draw_Map_At ({n}); -).
Include (-
! From fizmo's _streams_z_ucs_output
Array Automap_Unicode_Conv -->
0 $2500 $2502 63 63 63 63 63 63 63 63 11 12 13 14 15 ! 0 - 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ! 16 - 31
32 $2190 $2192 47 92 32 $2500 $2500 $2502 $2502 $2534 $252c $251c $2524 $2301 $2308 ! 32 - 47
! 32 $2190 $2192 $2571 $2572 32 $2500 $2500 $2502 $2502 $2534 $252c $251c $2524 $2301 $2308 ! 32 - 47
$2309 $230b $2534 $252c $251c $2524 $2588 $2580 $2584 $258c $2590 $2584 $2580 $258c $2590 $259d ! 48 - 63
$2597 $2596 $2598 $259d $2597 $2596 $2598 43 43 43 43 $2594 95 $23b9 $2595 32 ! 64 - 79
$258f $258e $258d $258c $258b $258a $2589 $2588 $2595 $258f $2573 $253c $2191 $2193 $2195 $25a2 ! 80 - 95
63 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ! 96 - 111
112 113 114 115 116 117 118 119 120 121 122 $2191 $2193 $2195 63 127 ! 112 - 127
;
Array Automap_Font_0_Conv -> 0 45 166 73 79 73 105 45 105 63 63 11 12 13 14 15 ! 0 - 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ! 16 - 31
32 33 34 47 92 32 45 45 166 166 45 45 166 166 45 45 ! 32 - 47
45 45 47 92 47 92 42 45 45 166 166 45 45 166 166 45 ! 48 - 63
45 45 45 45 45 45 45 71 72 73 74 75 76 77 78 79 ! 64 - 79
80 81 82 83 84 85 86 87 88 89 88 43 85 68 59 45 ! 80 - 95
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 45 ! 96 - 111
112 113 114 115 116 117 118 119 120 121 122 94 118 59 126 127 ! 112 - 127
;
Array Automap_Font_3_Conv -> 0 38 40 96 96 96 126 126 126 96 126 11 12 13 14 15 ! 0 - 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ! 16 - 31
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ! 32 - 47
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 ! 48 - 63
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ! 64 - 79
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 ! 80 - 95
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ! 96 - 111
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 ! 112 - 127
;
[ I6_Draw_Map_At line_n width posa posb ctr ch graphic_mode transform_table hyperlink_room;
++ line_n;
posa = line_n + 1;
width = VM_ScreenWidth();
graphic_mode = 0;
if ( (+ current displayness +) == (+ map display fancy +) or (+ map display automatic +) ) {
#Ifdef TARGET_ZCODE;
@set_font 3 graphic_mode; ! TODO: Make this glulx friendly
#endif;
if ( (+ current displayness +) == (+ map display fancy +) ) {
graphic_mode = 3;
}
}
if ( (+ current displayness +) == (+ map display unicode +) ) {
#ifdef TARGET_ZCODE;
graphic_mode = -1;
#ifnot;
if (unicode_gestalt_ok) {
graphic_mode = -1;
} else {
graphic_mode = 0;
}
#endif;
}
transform_table = Automap_Font_0_Conv;
if (graphic_mode == 0) {
#ifdef AUTOMAP_VISIBLE_BACKGROUND;
transform_table->32 = '.';
#endif;
} else if (graphic_mode == -1) {
transform_table = Automap_Unicode_Conv;
#ifdef AUTOMAP_VISIBLE_BACKGROUND;
transform_table-->32 = 71;
#endif;
} else {
transform_table = Automap_Font_3_Conv;
#ifdef AUTOMAP_VISIBLE_BACKGROUND;
transform_table->32 = 71;
#endif;
}
#ifdef TARGET_ZCODE;
@set_window 1;
#ifnot;
! TODO
#endif;
ctr = 0;
for (posa = line_n: posa < MAP_HEIGHT + line_n: ++ posa) {
posb = width - MAP_WIDTH - 1;
VM_MoveCursorInStatusLine (posa, posb);;
for (posb = 0: posb < MAP_WIDTH: ++ posb) {
#ifdef AUTOMAP_HYPERLINKS;
hyperlink_room = Automap_links --> (ctr);
if (hyperlink_room ~= 0) {
! TODO copy-pasted from Basic Hyperlinks - Is there a way to call instead?
if (glk_gestalt(gestalt_Hyperlinks, 0)) glk_set_hyperlink(hyperlink_room);
! set room link to hyperlink_room;
! !say "[set slink hyperlink_room]"; ;
}
if (graphic_mode == -1) {
#ifdef TARGET_ZCODE;
ch = transform_table-->(Automap_Chars->( ctr ++ ));
@print_unicode ch;
#ifnot;
glk_put_char_uni (transform_table-->(Automap_Chars->( ctr ++ )));
#endif;
} else
print (char) transform_table->(Automap_Chars->( ctr ++ ));
if (hyperlink_room ~= 0) {
! TODO copy-pasted from Basic Hyperlinks - Is there a way to call instead?
if (glk_gestalt(gestalt_Hyperlinks, 0)) glk_set_hyperlink(0);
!end room link;
}
! say "[end xlink]"; ;
#ifnot;
if (graphic_mode == -1) {
#ifdef TARGET_ZCODE;
ch = transform_table-->(Automap_Chars->( ctr ++ ));
@print_unicode ch;
#ifnot;
glk_put_char_uni (transform_table-->(Automap_Chars->( ctr ++ )));
#endif;
} else
print (char) transform_table->(Automap_Chars->( ctr ++ ));
#endif;
}
}
#ifdef TARGET_ZCODE;
if (graphic_mode > 0)
@set_font 1 posa;
style roman;
font on;
#ifnot;
! TODO
#endif;
#ifdef AUTOMAP_HYPERLINKS;
glk_request_hyperlink_event(gg_statuswin);
#endif;
];
-);
The automap size is a number that varies. The automap size is usually 9. When play begins: if automap size is at least 1, reserve automap memory of automap size rows.
To say (n - a number) blank lines:
while n > 0:
say "[line break]";
decrease n by 1.
Section 5 - Hyperlink specific stuff (for use with Basic Hyperlinks by Emily Short)
[To set linked room to (x - a number):
say "[set link x]".
To end linked room:
say "[end link]".]
[copied from Safari Guide by Emily Short ch 16.10 ]
Hyperlink moving to room is an action applying to one thing.
Check hyperlink moving to room:
if the noun is the location, say "You're already in [the location]." instead.
Carry out hyperlink moving to room:
while the player is not in the noun:
let heading be the best route from the location to the noun through visited rooms, using even locked doors;
if heading is not a direction, say "You can't think how to get there from here." instead;
let destination be the room heading from the location;
say "(heading [heading])[command clarification break]";
try going heading;
if the player is not in the destination, rule fails.
To decide what room is the glulx equivalent of (n - a number):
(- {n} -)
To decide whether (n - a number) codes a glulx object:
(- (metaclass({n}) == Object) -)
Section 99 - Debug verbs - Not for release
[To check hyperlink availability:
(- if (glk_gestalt(gestalt_Hyperlinks, 0))
print "Hyperlinks supported!^";
else
print "Hyperlinks not supported!^";
-).
When play begins:
if the automap hyperlinks option is active,
Check hyperlink availability.
]
Map viewing is an action out of world applying to nothing. Understand "map view" as map viewing.
Carry out map viewing:
say "Viewing rooms coregional with [location].";
repeat with viewed room running through all rooms coregional with location begin;
say "[viewed room] [if viewed room is not currently_mapped](currently unmapped ???) [end if]is at [map_x of viewed room], [map_y of viewed room].";
end repeat;
say "[line break]Viewing rooms not coregional with [location].";
repeat with viewed room running through all rooms not coregional with location begin;
say "[viewed room] [if viewed room is not currently_mapped](currently unmapped) [end if]is at [map_x of viewed room], [map_y of viewed room].";
end repeat;
Map dumping is an action out of world applying to nothing. Understand "map dump" as map dumping.
Map link dumping is an action out of world applying to nothing. Understand "map link dump" as map link dumping.
Include (-
[ Automap_dump i;
for (i = 0: i < MAP_WIDTH * MAP_HEIGHT; ++ i)
print Automap_chars->i, " ";
];
[ Automap_link_dump i j;
#ifdef AUTOMAP_HYPERLINKS;
for (i = 0; i < MAP_WIDTH * MAP_HEIGHT; ++ i) {
j = Automap_links --> i;
if (j ~= 0 && glk_gestalt(gestalt_Hyperlinks, 0))
glk_set_hyperlink(j);
print j, " ";
if (j ~= 0 && glk_gestalt(gestalt_Hyperlinks, 0))
glk_set_hyperlink(0);
}
#endif;
];
-);
To say automap dump:
(- Automap_dump(); -).
To say automap link dump:
(- Automap_link_dump(); -).
Carry out map dumping:
say "MAP DUMP:[line break][automap dump].".
Carry out map link dumping:
say "MAP LINK DUMP:[line break][automap link dump].".
Modified Automap ends here.
---- DOCUMENTATION ----
Automap will watch what rooms the player has visited and create a Beyond Zork style automap.