about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG.md25
-rw-r--r--CMakeLists.txt10
-rw-r--r--README.md17
-rw-r--r--VERSION2
-rw-r--r--assets/subway.yaml115
-rw-r--r--src/game_data.cpp17
-rw-r--r--src/game_data.h6
-rw-r--r--src/network_set.cpp29
-rw-r--r--src/network_set.h16
-rw-r--r--src/subway_map.cpp83
-rw-r--r--src/tracker_frame.cpp1
-rw-r--r--src/version.h2
13 files changed, 229 insertions, 95 deletions
diff --git a/.gitignore b/.gitignore index a7cadc7..1ca77eb 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,5 +1,6 @@
1build/ 1build/
2builds/ 2builds/
3assets/LL1.yaml 3assets/LL1.yaml
4assets/ids.yaml
4.DS_Store 5.DS_Store
5.vs 6.vs
diff --git a/CHANGELOG.md b/CHANGELOG.md index a9ce76d..256b63d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,5 +1,30 @@
1# lingo-ap-tracker Releases 1# lingo-ap-tracker Releases
2 2
3## v0.11.2 - 2024-09-24
4
5- One-way connections on the subway map are now indicated by a circle at the
6 exit. Contributed by art0007i.
7
8Download:
9[lingo-ap-tracker-v0.11.2-win64.zip](https://files.fourisland.com/releases/lingo-ap-tracker/lingo-ap-tracker-v0.11.2-win64.zip)<br/>
10Source: [v0.11.2](https://code.fourisland.com/lingo-ap-tracker/tag/?h=v0.11.2)
11
12## v0.11.1 - 2024-07-25
13
14- The Pilgrim Antechamber sunwarp on the subway map now shows all sunwarp
15 connections, and is red if a pilgrimage is not possible.
16- The save analysis panel now uses the remote location status for non-counting
17 panels.
18- Fixed positioning of Outside The Undeterred - Number Hunt door on subway map.
19- Fixed subway map issue when sunwarp shuffle and individual/progressive sunwarp
20 access were combined where the icons on the map would show unshuffled access.
21- Map area indicators now correctly treat unreachable pre-checked paintings as
22 unchecked.
23
24Download:
25[lingo-ap-tracker-v0.11.1-win64.zip](https://files.fourisland.com/releases/lingo-ap-tracker/lingo-ap-tracker-v0.11.1-win64.zip)<br/>
26Source: [v0.11.1](https://code.fourisland.com/lingo-ap-tracker/tag/?h=v0.11.1)
27
3## v0.11.0 - 2024-07-19 28## v0.11.0 - 2024-07-19
4 29
5- Added a savedata analyzer. When connected to a world, the user can open up the 30- Added a savedata analyzer. When connected to a world, the user can open up the
diff --git a/CMakeLists.txt b/CMakeLists.txt index e1cb7f0..4eef9d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -54,3 +54,13 @@ add_executable(lingo_ap_tracker
54set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 20) 54set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 20)
55set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) 55set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON)
56target_link_libraries(lingo_ap_tracker PRIVATE fmt::fmt OpenSSL::SSL OpenSSL::Crypto websocketpp::websocketpp wx::core wx::base wx::net yaml-cpp::yaml-cpp) 56target_link_libraries(lingo_ap_tracker PRIVATE fmt::fmt OpenSSL::SSL OpenSSL::Crypto websocketpp::websocketpp wx::core wx::base wx::net yaml-cpp::yaml-cpp)
57
58set(SRC_DIR "${CMAKE_SOURCE_DIR}/assets")
59set(DST_DIR "${CMAKE_BINARY_DIR}/$<CONFIG>/assets")
60
61add_custom_target(copy_assets ALL
62 COMMAND ${CMAKE_COMMAND} -E copy_directory ${SRC_DIR} ${DST_DIR}
63 COMMENT "Copying folder from ${SRC_DIR} to ${DST_DIR}"
64)
65
66add_dependencies(lingo_ap_tracker copy_assets)
diff --git a/README.md b/README.md index 83525dd..1fbbc2f 100644 --- a/README.md +++ b/README.md
@@ -9,4 +9,19 @@ Releases of the tracker can be found [on the releases page](https://code.fourisl
9 9
10## Acknowledgments 10## Acknowledgments
11 11
12Thanks to Kinrah for making the subway map image! 12* Brenton Wildes: Created Lingo, and drew some of the images used in the tracker.
13* Kinrah: Made the subway map image.
14* art0007i: Contributed to the display of the subway map.
15
16## Building
17
18To build the app:
19
201. Clone the repository including submodules: `git clone --recursive https://code.fourisland.com/lingo-ap-tracker`
212. Put [LL1.yaml from archipelago](https://github.com/ArchipelagoMW/Archipelago/raw/main/worlds/lingo/data/LL1.yaml) in ./assets
223. Put [ids.yaml from archipelago](https://github.com/ArchipelagoMW/Archipelago/raw/main/worlds/lingo/data/ids.yaml) in ./assets
234. Configure the project: `cmake --preset=lingo-ap-tracker-preset`
245. Build the application in debug mode: `cmake --build --preset=lingo-ap-tracker-preset`
256. (Optional) Build the application in release mode: `cmake --build --preset=x64-release-preset`
26
27LL1.yaml and ids.yaml sometimes receive breaking changes that need to be kept in sync with the tracker. If the application crashes with an unknown error, try making sure that you are using the right versions of those files. In general, the main branch of the tracker will require config files from the latest Archipelago release. Branches may require config files from Archipelago main, or from pending pull requests.
diff --git a/VERSION b/VERSION index e88c34f..1554d9b 100644 --- a/VERSION +++ b/VERSION
@@ -1 +1 @@
v0.11.0 \ No newline at end of file v0.11.2 \ No newline at end of file
diff --git a/assets/subway.yaml b/assets/subway.yaml index dcc58b2..87be8cc 100644 --- a/assets/subway.yaml +++ b/assets/subway.yaml
@@ -14,42 +14,42 @@
14 door: Painting Shortcut 14 door: Painting Shortcut
15 paintings: 15 paintings:
16 - garden_painting_tower2 16 - garden_painting_tower2
17 tags: 17 entrances:
18 - garden_starting 18 - garden_starting
19- pos: [1066, 841] 19- pos: [1066, 841]
20 room: Courtyard 20 room: Courtyard
21 door: Painting Shortcut 21 door: Painting Shortcut
22 paintings: 22 paintings:
23 - flower_painting_8 23 - flower_painting_8
24 tags: 24 entrances:
25 - flower_starting 25 - flower_starting
26- pos: [905, 895] 26- pos: [905, 895]
27 room: The Wondrous (Doorknob) 27 room: The Wondrous (Doorknob)
28 door: Painting Shortcut 28 door: Painting Shortcut
29 paintings: 29 paintings:
30 - symmetry_painting_a_starter 30 - symmetry_painting_a_starter
31 tags: 31 entrances:
32 - symmetry_starting 32 - symmetry_starting
33- pos: [1066, 868] 33- pos: [1066, 868]
34 room: Outside The Bold 34 room: Outside The Bold
35 door: Painting Shortcut 35 door: Painting Shortcut
36 paintings: 36 paintings:
37 - pencil_painting6 37 - pencil_painting6
38 tags: 38 entrances:
39 - pencil_starting 39 - pencil_starting
40- pos: [1066, 895] 40- pos: [1066, 895]
41 room: Outside The Undeterred 41 room: Outside The Undeterred
42 door: Painting Shortcut 42 door: Painting Shortcut
43 paintings: 43 paintings:
44 - blueman_painting_3 44 - blueman_painting_3
45 tags: 45 entrances:
46 - blueman_starting 46 - blueman_starting
47- pos: [905, 868] 47- pos: [905, 868]
48 room: Outside The Agreeable 48 room: Outside The Agreeable
49 door: Painting Shortcut 49 door: Painting Shortcut
50 paintings: 50 paintings:
51 - eyes_yellow_painting2 51 - eyes_yellow_painting2
52 tags: 52 entrances:
53 - street_starting 53 - street_starting
54- pos: [1211, 879] 54- pos: [1211, 879]
55 room: Hidden Room 55 room: Hidden Room
@@ -66,7 +66,7 @@
66- pos: [1116, 939] 66- pos: [1116, 939]
67 paintings: 67 paintings:
68 - owl_painting 68 - owl_painting
69 tags: 69 entrances:
70 - owl_hidden 70 - owl_hidden
71- pos: [986, 793] 71- pos: [986, 793]
72 room: Second Room 72 room: Second Room
@@ -89,7 +89,7 @@
89- pos: [1313, 686] 89- pos: [1313, 686]
90 paintings: 90 paintings:
91 - maze_painting 91 - maze_painting
92 tags: 92 exits:
93 - green_owl 93 - green_owl
94 - green_numbers 94 - green_numbers
95- pos: [1172, 760] 95- pos: [1172, 760]
@@ -108,7 +108,7 @@
108- pos: [1263, 867] 108- pos: [1263, 867]
109 paintings: 109 paintings:
110 - smile_painting_6 110 - smile_painting_6
111 tags: 111 entrances:
112 - smiley_deadend 112 - smiley_deadend
113- pos: [1012, 1086] 113- pos: [1012, 1086]
114 sunwarp: 114 sunwarp:
@@ -154,7 +154,7 @@
154- pos: [756, 400] 154- pos: [756, 400]
155 paintings: 155 paintings:
156 - smile_painting_4 156 - smile_painting_4
157 tags: 157 entrances:
158 - smiley_crossroads 158 - smiley_crossroads
159- pos: [878, 509] 159- pos: [878, 509]
160 sunwarp: 160 sunwarp:
@@ -208,7 +208,7 @@
208- pos: [1138, 287] 208- pos: [1138, 287]
209 paintings: 209 paintings:
210 - eyes_yellow_painting 210 - eyes_yellow_painting
211 tags: 211 exits:
212 - street_starting 212 - street_starting
213- pos: [1088, 385] 213- pos: [1088, 385]
214 sunwarp: 214 sunwarp:
@@ -220,7 +220,7 @@
220- pos: [1214, 457] 220- pos: [1214, 457]
221 paintings: 221 paintings:
222 - pencil_painting7 222 - pencil_painting7
223 tags: 223 entrances:
224 - pencil_compass 224 - pencil_compass
225- pos: [1196, 417] 225- pos: [1196, 417]
226 invisible: true 226 invisible: true
@@ -251,7 +251,7 @@
251- pos: [1477, 343] 251- pos: [1477, 343]
252 paintings: 252 paintings:
253 - garden_painting_tower 253 - garden_painting_tower
254 tags: 254 exits:
255 - garden_starting 255 - garden_starting
256- pos: [1565, 311] 256- pos: [1565, 311]
257 room: The Fearless (First Floor) 257 room: The Fearless (First Floor)
@@ -271,17 +271,17 @@
271- pos: [1784, 569] 271- pos: [1784, 569]
272 paintings: 272 paintings:
273 - crown_painting 273 - crown_painting
274 tags: 274 exits:
275 - crown_tower6 275 - crown_tower6
276- pos: [1653, 717] 276- pos: [1653, 717]
277 paintings: 277 paintings:
278 - eight_painting2 278 - eight_painting2
279 tags: 279 entrances:
280 - eight_alcove 280 - eight_alcove
281- pos: [1653, 662] 281- pos: [1653, 662]
282 paintings: 282 paintings:
283 - eight_painting 283 - eight_painting
284 tags: 284 exits:
285 - eight_alcove 285 - eight_alcove
286- pos: [697, 1471] 286- pos: [697, 1471]
287 room: Orange Tower 287 room: Orange Tower
@@ -402,7 +402,7 @@
402- pos: [844, 134] 402- pos: [844, 134]
403 paintings: 403 paintings:
404 - smile_painting_8 404 - smile_painting_8
405 tags: 405 entrances:
406 - smiley_hotcrusts 406 - smiley_hotcrusts
407- pos: [797, 155] 407- pos: [797, 155]
408 sunwarp: 408 sunwarp:
@@ -435,12 +435,13 @@
435 - colors_painting2 435 - colors_painting2
436 - cherry_painting2 436 - cherry_painting2
437 - hi_solved_painting 437 - hi_solved_painting
438 tags: 438 entrances:
439 - owl_tower6 439 - owl_tower6
440 - clock_tower6 440 - clock_tower6
441 - panda_tower6 441 - panda_tower6
442 - crown_tower6 442 - crown_tower6
443 - apple_tower6 443 - apple_tower6
444 exits:
444 - hi_scientific 445 - hi_scientific
445- pos: [349, 1124] 446- pos: [349, 1124]
446 paintings: 447 paintings:
@@ -457,7 +458,7 @@
457- pos: [556, 233] 458- pos: [556, 233]
458 paintings: 459 paintings:
459 - flower_painting_7 460 - flower_painting_7
460 tags: 461 exits:
461 - flower_starting 462 - flower_starting
462 - flower_arrow 463 - flower_arrow
463- pos: [600, 332] 464- pos: [600, 332]
@@ -466,7 +467,7 @@
466- pos: [579, 350] 467- pos: [579, 350]
467 paintings: 468 paintings:
468 - blueman_painting 469 - blueman_painting
469 tags: 470 entrances:
470 - blueman_courtyard 471 - blueman_courtyard
471- pos: [530, 310] 472- pos: [530, 310]
472 room: First Second Third Fourth 473 room: First Second Third Fourth
@@ -508,7 +509,7 @@
508 room: Welcome Back Area 509 room: Welcome Back Area
509 door: Shortcut to Starting Room 510 door: Shortcut to Starting Room
510- pos: [773, 954] 511- pos: [773, 954]
511 tags: 512 exits:
512 - hub_wb 513 - hub_wb
513 - wondrous_wb 514 - wondrous_wb
514 - undeterred_wb 515 - undeterred_wb
@@ -519,31 +520,31 @@
519 - scientific_wb 520 - scientific_wb
520 - cellar_wb 521 - cellar_wb
521- pos: [1107, 749] 522- pos: [1107, 749]
522 tags: 523 entrances:
523 - hub_wb 524 - hub_wb
524- pos: [408, 817] 525- pos: [408, 817]
525 tags: 526 entrances:
526 - wondrous_wb 527 - wondrous_wb
527- pos: [281, 1017] 528- pos: [281, 1017]
528 tags: 529 entrances:
529 - undeterred_wb 530 - undeterred_wb
530- pos: [1017, 289] 531- pos: [1017, 289]
531 tags: 532 entrances:
532 - agreeable_wb 533 - agreeable_wb
533- pos: [907, 1385] 534- pos: [907, 1385]
534 tags: 535 entrances:
535 - wanderer_wb 536 - wanderer_wb
536- pos: [1737, 1053] 537- pos: [1737, 1053]
537 tags: 538 entrances:
538 - gallery_wb 539 - gallery_wb
539- pos: [1690, 268] 540- pos: [1690, 268]
540 tags: 541 entrances:
541 - observant_wb 542 - observant_wb
542- pos: [250, 604] 543- pos: [250, 604]
543 tags: 544 entrances:
544 - scientific_wb 545 - scientific_wb
545- pos: [1553, 1467] 546- pos: [1553, 1467]
546 tags: 547 entrances:
547 - cellar_wb 548 - cellar_wb
548- pos: [1478, 498] 549- pos: [1478, 498]
549 room: Owl Hallway 550 room: Owl Hallway
@@ -554,8 +555,9 @@
554 - maze_painting_2 555 - maze_painting_2
555 - owl_painting_2 556 - owl_painting_2
556 - clock_painting_4 557 - clock_painting_4
557 tags: 558 entrances:
558 - green_owl 559 - green_owl
560 exits:
559 - owl_hidden 561 - owl_hidden
560 - owl_tower6 562 - owl_tower6
561- pos: [1478, 938] 563- pos: [1478, 938]
@@ -600,13 +602,13 @@
600- pos: [1530, 938] 602- pos: [1530, 938]
601 paintings: 603 paintings:
602 - clock_painting_5 604 - clock_painting_5
603 tags: 605 entrances:
604 - clock_initiated 606 - clock_initiated
605- pos: [1546, 938] 607- pos: [1546, 938]
606 paintings: 608 paintings:
607 - clock_painting_2 609 - clock_painting_2
608 - arrows_painting_2 610 - arrows_painting_2
609 tags: 611 exits:
610 - clock_tower6 612 - clock_tower6
611 - clock_initiated 613 - clock_initiated
612- pos: [1579, 813] 614- pos: [1579, 813]
@@ -616,7 +618,7 @@
616- pos: [1444, 896] 618- pos: [1444, 896]
617 paintings: 619 paintings:
618 - smile_painting_1 620 - smile_painting_1
619 tags: 621 entrances:
620 - smiley_initiated 622 - smiley_initiated
621- pos: [1430, 691] 623- pos: [1430, 691]
622 room: Outside The Undeterred 624 room: Outside The Undeterred
@@ -630,6 +632,7 @@
630 - blue_ch 632 - blue_ch
631 - yellow_ch 633 - yellow_ch
632 - green_ch 634 - green_ch
635 exits:
633 - early_ch 636 - early_ch
634- pos: [1567, 1264] 637- pos: [1567, 1264]
635 tags: 638 tags:
@@ -656,7 +659,7 @@
656 paintings: 659 paintings:
657 - pencil_painting2 660 - pencil_painting2
658 - north_missing2 661 - north_missing2
659 tags: 662 exits:
660 - pencil_compass 663 - pencil_compass
661 - pencil_starting 664 - pencil_starting
662 - pencil_directional 665 - pencil_directional
@@ -664,7 +667,7 @@
664 room: Outside The Bold 667 room: Outside The Bold
665 door: Steady Entrance 668 door: Steady Entrance
666- pos: [445, 1048] 669- pos: [445, 1048]
667 tags: 670 exits:
668 - undeterred_artistic 671 - undeterred_artistic
669- pos: [279, 1071] 672- pos: [279, 1071]
670 room: Number Hunt 673 room: Number Hunt
@@ -684,7 +687,7 @@
684- pos: [60, 1017] 687- pos: [60, 1017]
685 paintings: 688 paintings:
686 - blueman_painting_2 689 - blueman_painting_2
687 tags: 690 exits:
688 - blueman_courtyard 691 - blueman_courtyard
689 - blueman_starting 692 - blueman_starting
690- pos: [402, 1012] 693- pos: [402, 1012]
@@ -692,7 +695,7 @@
692 door: Green Painting 695 door: Green Painting
693 paintings: 696 paintings:
694 - maze_painting_3 697 - maze_painting_3
695 tags: 698 entrances:
696 - green_numbers 699 - green_numbers
697- pos: [134, 1007] 700- pos: [134, 1007]
698 sunwarp: 701 sunwarp:
@@ -727,7 +730,7 @@
727 door: Eights 730 door: Eights
728 paintings: 731 paintings:
729 - smile_painting_5 732 - smile_painting_5
730 tags: 733 entrances:
731 - smiley_numbers 734 - smiley_numbers
732- pos: [557, 953] 735- pos: [557, 953]
733 room: Number Hunt 736 room: Number Hunt
@@ -753,24 +756,24 @@
753- pos: [351, 927] 756- pos: [351, 927]
754 paintings: 757 paintings:
755 - boxes_painting 758 - boxes_painting
756 tags: 759 entrances:
757 - lattice_directional 760 - lattice_directional
758- pos: [272, 927] 761- pos: [272, 927]
759 paintings: 762 paintings:
760 - smile_painting_7 763 - smile_painting_7
761 tags: 764 entrances:
762 - smiley_directional 765 - smiley_directional
763- pos: [214, 822] 766- pos: [214, 822]
764 paintings: 767 paintings:
765 - cherry_painting 768 - cherry_painting
766 tags: 769 entrances:
767 - apple_directional 770 - apple_directional
768- pos: [266, 735] 771- pos: [266, 735]
769 room: Number Hunt 772 room: Number Hunt
770 door: Sixes 773 door: Sixes
771 paintings: 774 paintings:
772 - pencil_painting3 775 - pencil_painting3
773 tags: 776 entrances:
774 - pencil_directional 777 - pencil_directional
775- pos: [215, 735] 778- pos: [215, 735]
776 paintings: 779 paintings:
@@ -838,7 +841,7 @@
838- pos: [1653, 101] 841- pos: [1653, 101]
839 paintings: 842 paintings:
840 - smile_painting_9 843 - smile_painting_9
841 tags: 844 exits:
842 - smiley_crossroads 845 - smiley_crossroads
843 - smiley_deadend 846 - smiley_deadend
844 - smiley_hotcrusts 847 - smiley_hotcrusts
@@ -851,12 +854,12 @@
851 room: The Artistic (Smiley) 854 room: The Artistic (Smiley)
852 door: Door to Panda 855 door: Door to Panda
853- pos: [1711, 140] 856- pos: [1711, 140]
854 tags: 857 entrances:
855 - undeterred_artistic 858 - undeterred_artistic
856- pos: [1653, 169] 859- pos: [1653, 169]
857 paintings: 860 paintings:
858 - panda_painting_3 861 - panda_painting_3
859 tags: 862 exits:
860 - panda_tower6 863 - panda_tower6
861 - panda_hallway 864 - panda_hallway
862- pos: [1708, 171] 865- pos: [1708, 171]
@@ -865,7 +868,7 @@
865- pos: [1761, 169] 868- pos: [1761, 169]
866 paintings: 869 paintings:
867 - boxes_painting2 870 - boxes_painting2
868 tags: 871 exits:
869 - lattice_directional 872 - lattice_directional
870- pos: [1762, 139] 873- pos: [1762, 139]
871 room: The Artistic (Lattice) 874 room: The Artistic (Lattice)
@@ -873,7 +876,7 @@
873- pos: [1761, 101] 876- pos: [1761, 101]
874 paintings: 877 paintings:
875 - cherry_painting3 878 - cherry_painting3
876 tags: 879 exits:
877 - apple_tower6 880 - apple_tower6
878 - apple_directional 881 - apple_directional
879- pos: [1708, 107] 882- pos: [1708, 107]
@@ -886,7 +889,7 @@
886 paintings: 889 paintings:
887 - eye_painting_2 890 - eye_painting_2
888 - smile_painting_2 891 - smile_painting_2
889 tags: 892 entrances:
890 - smiley_theysee 893 - smiley_theysee
891- pos: [310, 750] 894- pos: [310, 750]
892 room: The Eyes They See 895 room: The Eyes They See
@@ -908,7 +911,7 @@
908 - symmetry_painting_b_2 911 - symmetry_painting_b_2
909 - symmetry_painting_a_6 912 - symmetry_painting_a_6
910 - symmetry_painting_b_6 913 - symmetry_painting_b_6
911 tags: 914 exits:
912 - symmetry_starting 915 - symmetry_starting
913- pos: [407, 755] 916- pos: [407, 755]
914 room: The Wondrous 917 room: The Wondrous
@@ -918,12 +921,12 @@
918- pos: [449, 755] 921- pos: [449, 755]
919 paintings: 922 paintings:
920 - flower_painting_6 923 - flower_painting_6
921 tags: 924 entrances:
922 - flower_arrow 925 - flower_arrow
923- pos: [1101, 222] 926- pos: [1101, 222]
924 paintings: 927 paintings:
925 - panda_painting 928 - panda_painting
926 tags: 929 entrances:
927 - panda_hallway 930 - panda_hallway
928- pos: [1152, 209] 931- pos: [1152, 209]
929 room: Hallway Room (1) 932 room: Hallway Room (1)
@@ -977,16 +980,16 @@
977 - scenery_painting_0a 980 - scenery_painting_0a
978 - map_painting 981 - map_painting
979 - fruitbowl_painting4 982 - fruitbowl_painting4
980 tags: 983 entrances:
981 - smiley_gallery 984 - smiley_gallery
982- pos: [1120, 1286] 985- pos: [1120, 1286]
983 room: Rhyme Room (Smiley) 986 room: Rhyme Room (Smiley)
984 door: Door to Target 987 door: Door to Target
985- pos: [1120, 1315] 988- pos: [1120, 1315]
986 tags: 989 entrances: # this could be considered 2 way since the subway map has a one way gate at the exit anyway
987 - rhyme_smiley_target 990 - rhyme_smiley_target
988- pos: [792, 1137] 991- pos: [792, 1137]
989 tags: 992 exits:
990 - rhyme_smiley_target 993 - rhyme_smiley_target
991- pos: [895, 1217] 994- pos: [895, 1217]
992 room: Number Hunt 995 room: Number Hunt
@@ -1030,7 +1033,7 @@
1030- pos: [294, 602] 1033- pos: [294, 602]
1031 paintings: 1034 paintings:
1032 - hi_solved_painting4 1035 - hi_solved_painting4
1033 tags: 1036 entrances:
1034 - hi_scientific 1037 - hi_scientific
1035- pos: [814, 1001] 1038- pos: [814, 1001]
1036 room: Challenge Room 1039 room: Challenge Room
diff --git a/src/game_data.cpp b/src/game_data.cpp index c39e239..7b805df 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp
@@ -681,6 +681,18 @@ struct GameData {
681 } 681 }
682 } 682 }
683 683
684 if (subway_it["entrances"]) {
685 for (const auto &entrance_it : subway_it["entrances"]) {
686 subway_item.entrances.push_back(entrance_it.as<std::string>());
687 }
688 }
689
690 if (subway_it["exits"]) {
691 for (const auto &exit_it : subway_it["exits"]) {
692 subway_item.exits.push_back(exit_it.as<std::string>());
693 }
694 }
695
684 if (subway_it["sunwarp"]) { 696 if (subway_it["sunwarp"]) {
685 SubwaySunwarp sunwarp; 697 SubwaySunwarp sunwarp;
686 sunwarp.dots = subway_it["sunwarp"]["dots"].as<int>(); 698 sunwarp.dots = subway_it["sunwarp"]["dots"].as<int>();
@@ -792,6 +804,11 @@ GameData &GetState() {
792 804
793} // namespace 805} // namespace
794 806
807bool SubwayItem::HasWarps() const {
808 return !(this->tags.empty() && this->entrances.empty() &&
809 this->exits.empty());
810}
811
795bool SubwaySunwarp::operator<(const SubwaySunwarp &rhs) const { 812bool SubwaySunwarp::operator<(const SubwaySunwarp &rhs) const {
796 return std::tie(dots, type) < std::tie(rhs.dots, rhs.type); 813 return std::tie(dots, type) < std::tie(rhs.dots, rhs.type);
797} 814}
diff --git a/src/game_data.h b/src/game_data.h index 3179365..1f6d247 100644 --- a/src/game_data.h +++ b/src/game_data.h
@@ -148,9 +148,13 @@ struct SubwayItem {
148 int y; 148 int y;
149 std::optional<int> door; 149 std::optional<int> door;
150 std::vector<std::string> paintings; 150 std::vector<std::string> paintings;
151 std::vector<std::string> tags; 151 std::vector<std::string> tags; // 2-way teleports
152 std::vector<std::string> entrances; // teleport entrances
153 std::vector<std::string> exits; // teleport exits
152 std::optional<SubwaySunwarp> sunwarp; 154 std::optional<SubwaySunwarp> sunwarp;
153 std::optional<std::string> special; 155 std::optional<std::string> special;
156
157 bool HasWarps() const;
154}; 158};
155 159
156const std::vector<MapArea>& GD_GetMapAreas(); 160const std::vector<MapArea>& GD_GetMapAreas();
diff --git a/src/network_set.cpp b/src/network_set.cpp index 2a9e12c..45911e3 100644 --- a/src/network_set.cpp +++ b/src/network_set.cpp
@@ -4,9 +4,8 @@ void NetworkSet::Clear() {
4 network_by_item_.clear(); 4 network_by_item_.clear();
5} 5}
6 6
7void NetworkSet::AddLink(int id1, int id2) { 7void NetworkSet::AddLink(int id1, int id2, bool two_way) {
8 if (id2 > id1) { 8 if (two_way && id2 > id1) {
9 // Make sure id1 < id2
10 std::swap(id1, id2); 9 std::swap(id1, id2);
11 } 10 }
12 11
@@ -17,13 +16,14 @@ void NetworkSet::AddLink(int id1, int id2) {
17 network_by_item_[id2] = {}; 16 network_by_item_[id2] = {};
18 } 17 }
19 18
20 network_by_item_[id1].insert({id1, id2}); 19 NetworkNode node = {id1, id2, two_way};
21 network_by_item_[id2].insert({id1, id2}); 20
21 network_by_item_[id1].insert(node);
22 network_by_item_[id2].insert(node);
22} 23}
23 24
24void NetworkSet::AddLinkToNetwork(int network_id, int id1, int id2) { 25void NetworkSet::AddLinkToNetwork(int network_id, int id1, int id2, bool two_way) {
25 if (id2 > id1) { 26 if (two_way && id2 > id1) {
26 // Make sure id1 < id2
27 std::swap(id1, id2); 27 std::swap(id1, id2);
28 } 28 }
29 29
@@ -31,13 +31,22 @@ void NetworkSet::AddLinkToNetwork(int network_id, int id1, int id2) {
31 network_by_item_[network_id] = {}; 31 network_by_item_[network_id] = {};
32 } 32 }
33 33
34 network_by_item_[network_id].insert({id1, id2}); 34 NetworkNode node = {id1, id2, two_way};
35
36 network_by_item_[network_id].insert(node);
35} 37}
36 38
37bool NetworkSet::IsItemInNetwork(int id) const { 39bool NetworkSet::IsItemInNetwork(int id) const {
38 return network_by_item_.count(id); 40 return network_by_item_.count(id);
39} 41}
40 42
41const std::set<std::pair<int, int>>& NetworkSet::GetNetworkGraph(int id) const { 43const std::set<NetworkNode>& NetworkSet::GetNetworkGraph(int id) const {
42 return network_by_item_.at(id); 44 return network_by_item_.at(id);
43} 45}
46
47bool NetworkNode::operator<(const NetworkNode& rhs) const {
48 if (entry != rhs.entry) return entry < rhs.entry;
49 if (exit != rhs.exit) return exit < rhs.exit;
50 if (two_way != rhs.two_way) return two_way < rhs.two_way;
51 return false;
52}
diff --git a/src/network_set.h b/src/network_set.h index cec3f39..0f72052 100644 --- a/src/network_set.h +++ b/src/network_set.h
@@ -7,21 +7,29 @@
7#include <utility> 7#include <utility>
8#include <vector> 8#include <vector>
9 9
10struct NetworkNode {
11 int entry;
12 int exit;
13 bool two_way;
14
15 bool operator<(const NetworkNode& rhs) const;
16};
17
10class NetworkSet { 18class NetworkSet {
11 public: 19 public:
12 void Clear(); 20 void Clear();
13 21
14 void AddLink(int id1, int id2); 22 void AddLink(int id1, int id2, bool two_way);
15 23
16 void AddLinkToNetwork(int network_id, int id1, int id2); 24 void AddLinkToNetwork(int network_id, int id1, int id2, bool two_way);
17 25
18 bool IsItemInNetwork(int id) const; 26 bool IsItemInNetwork(int id) const;
19 27
20 const std::set<std::pair<int, int>>& GetNetworkGraph(int id) const; 28 const std::set<NetworkNode>& GetNetworkGraph(int id) const;
21 29
22 private: 30 private:
23 31
24 std::map<int, std::set<std::pair<int, int>>> network_by_item_; 32 std::map<int, std::set<NetworkNode>> network_by_item_;
25}; 33};
26 34
27#endif /* end of include guard: NETWORK_SET_H_3036B8E3 */ 35#endif /* end of include guard: NETWORK_SET_H_3036B8E3 */
diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 5b3ff5f..f896693 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp
@@ -91,10 +91,12 @@ void SubwayMap::OnConnect() {
91 networks_.Clear(); 91 networks_.Clear();
92 92
93 std::map<std::string, std::vector<int>> tagged; 93 std::map<std::string, std::vector<int>> tagged;
94 std::map<std::string, std::vector<int>> entrances;
95 std::map<std::string, std::vector<int>> exits;
94 for (const SubwayItem &subway_item : GD_GetSubwayItems()) { 96 for (const SubwayItem &subway_item : GD_GetSubwayItems()) {
95 if (AP_HasEarlyColorHallways() && 97 if (AP_HasEarlyColorHallways() &&
96 subway_item.special == "starting_room_paintings") { 98 subway_item.special == "starting_room_paintings") {
97 tagged["early_ch"].push_back(subway_item.id); 99 entrances["early_ch"].push_back(subway_item.id);
98 } 100 }
99 101
100 if (AP_IsPaintingShuffle() && !subway_item.paintings.empty()) { 102 if (AP_IsPaintingShuffle() && !subway_item.paintings.empty()) {
@@ -104,17 +106,33 @@ void SubwayMap::OnConnect() {
104 for (const std::string &tag : subway_item.tags) { 106 for (const std::string &tag : subway_item.tags) {
105 tagged[tag].push_back(subway_item.id); 107 tagged[tag].push_back(subway_item.id);
106 } 108 }
109 for (const std::string &tag : subway_item.entrances) {
110 entrances[tag].push_back(subway_item.id);
111 }
112 for (const std::string &tag : subway_item.exits) {
113 exits[tag].push_back(subway_item.id);
114 }
107 115
108 if (!AP_IsSunwarpShuffle() && subway_item.sunwarp && 116 if (!AP_IsSunwarpShuffle() && subway_item.sunwarp) {
109 subway_item.sunwarp->type != SubwaySunwarpType::kFinal) {
110 std::string tag = fmt::format("sunwarp{}", subway_item.sunwarp->dots); 117 std::string tag = fmt::format("sunwarp{}", subway_item.sunwarp->dots);
111 tagged[tag].push_back(subway_item.id); 118 switch (subway_item.sunwarp->type) {
119 case SubwaySunwarpType::kEnter:
120 entrances[tag].push_back(subway_item.id);
121 break;
122 case SubwaySunwarpType::kExit:
123 exits[tag].push_back(subway_item.id);
124 break;
125 default:
126 break;
127 }
112 } 128 }
113 129
114 if (!AP_IsPilgrimageEnabled() && 130 if (!AP_IsPilgrimageEnabled()) {
115 (subway_item.special == "sun_painting" || 131 if (subway_item.special == "sun_painting") {
116 subway_item.special == "sun_painting_exit")) { 132 entrances["sun_painting"].push_back(subway_item.id);
117 tagged["sun_painting"].push_back(subway_item.id); 133 } else if (subway_item.special == "sun_painting_exit") {
134 exits["sun_painting"].push_back(subway_item.id);
135 }
118 } 136 }
119 } 137 }
120 138
@@ -143,13 +161,14 @@ void SubwayMap::OnConnect() {
143 toWarp.type = SubwaySunwarpType::kExit; 161 toWarp.type = SubwaySunwarpType::kExit;
144 } 162 }
145 163
146 tagged[tag].push_back(GD_GetSubwayItemForSunwarp(fromWarp)); 164 entrances[tag].push_back(GD_GetSubwayItemForSunwarp(fromWarp));
147 tagged[tag].push_back(GD_GetSubwayItemForSunwarp(toWarp)); 165 exits[tag].push_back(GD_GetSubwayItemForSunwarp(toWarp));
148 166
149 networks_.AddLinkToNetwork( 167 networks_.AddLinkToNetwork(
150 final_sunwarp_item, GD_GetSubwayItemForSunwarp(fromWarp), 168 final_sunwarp_item, GD_GetSubwayItemForSunwarp(fromWarp),
151 mapping.dots == 6 ? final_sunwarp_item 169 mapping.dots == 6 ? final_sunwarp_item
152 : GD_GetSubwayItemForSunwarp(toWarp)); 170 : GD_GetSubwayItemForSunwarp(toWarp),
171 false);
153 } 172 }
154 } 173 }
155 174
@@ -159,7 +178,17 @@ void SubwayMap::OnConnect() {
159 tag_it1++) { 178 tag_it1++) {
160 for (auto tag_it2 = std::next(tag_it1); tag_it2 != items.end(); 179 for (auto tag_it2 = std::next(tag_it1); tag_it2 != items.end();
161 tag_it2++) { 180 tag_it2++) {
162 networks_.AddLink(*tag_it1, *tag_it2); 181 // two links because tags are bi-directional
182 networks_.AddLink(*tag_it1, *tag_it2, true);
183 }
184 }
185 }
186
187 for (const auto &[tag, items] : entrances) {
188 if (!exits.contains(tag)) continue;
189 for (auto exit : exits[tag]) {
190 for (auto entrance : items) {
191 networks_.AddLink(entrance, exit, false);
163 } 192 }
164 } 193 }
165 } 194 }
@@ -179,7 +208,7 @@ void SubwayMap::UpdateIndicators() {
179 AP_GetPaintingMapping().at(painting_id)); 208 AP_GetPaintingMapping().at(painting_id));
180 209
181 if (from_id && to_id) { 210 if (from_id && to_id) {
182 networks_.AddLink(*from_id, *to_id); 211 networks_.AddLink(*from_id, *to_id, false);
183 } 212 }
184 } 213 }
185 } 214 }
@@ -192,7 +221,7 @@ void SubwayMap::UpdateIndicators() {
192void SubwayMap::UpdateSunwarp(SubwaySunwarp from_sunwarp, 221void SubwayMap::UpdateSunwarp(SubwaySunwarp from_sunwarp,
193 SubwaySunwarp to_sunwarp) { 222 SubwaySunwarp to_sunwarp) {
194 networks_.AddLink(GD_GetSubwayItemForSunwarp(from_sunwarp), 223 networks_.AddLink(GD_GetSubwayItemForSunwarp(from_sunwarp),
195 GD_GetSubwayItemForSunwarp(to_sunwarp)); 224 GD_GetSubwayItemForSunwarp(to_sunwarp), false);
196} 225}
197 226
198void SubwayMap::Zoom(bool in) { 227void SubwayMap::Zoom(bool in) {
@@ -358,10 +387,9 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
358 if (networks_.IsItemInNetwork(*hovered_item_)) { 387 if (networks_.IsItemInNetwork(*hovered_item_)) {
359 dc.SetBrush(*wxTRANSPARENT_BRUSH); 388 dc.SetBrush(*wxTRANSPARENT_BRUSH);
360 389
361 for (const auto &[item_id1, item_id2] : 390 for (const auto node : networks_.GetNetworkGraph(*hovered_item_)) {
362 networks_.GetNetworkGraph(*hovered_item_)) { 391 const SubwayItem &item1 = GD_GetSubwayItem(node.entry);
363 const SubwayItem &item1 = GD_GetSubwayItem(item_id1); 392 const SubwayItem &item2 = GD_GetSubwayItem(node.exit);
364 const SubwayItem &item2 = GD_GetSubwayItem(item_id2);
365 393
366 wxPoint item1_pos = MapPosToRenderPos( 394 wxPoint item1_pos = MapPosToRenderPos(
367 {item1.x + AREA_ACTUAL_SIZE / 2, item1.y + AREA_ACTUAL_SIZE / 2}); 395 {item1.x + AREA_ACTUAL_SIZE / 2, item1.y + AREA_ACTUAL_SIZE / 2});
@@ -381,6 +409,12 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
381 dc.DrawLine(item1_pos, item2_pos); 409 dc.DrawLine(item1_pos, item2_pos);
382 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2)); 410 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2));
383 dc.DrawLine(item1_pos, item2_pos); 411 dc.DrawLine(item1_pos, item2_pos);
412 if (!node.two_way) {
413 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 2));
414 dc.SetBrush(*wxCYAN_BRUSH);
415 dc.DrawCircle(item2_pos, 4);
416 dc.SetBrush(*wxTRANSPARENT_BRUSH);
417 }
384 } else { 418 } else {
385 int ellipse_x; 419 int ellipse_x;
386 int ellipse_y; 420 int ellipse_y;
@@ -423,6 +457,12 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
423 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2)); 457 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2));
424 dc.DrawEllipticArc(ellipse_x, ellipse_y, halfwidth * 2, 458 dc.DrawEllipticArc(ellipse_x, ellipse_y, halfwidth * 2,
425 halfheight * 2, start, end); 459 halfheight * 2, start, end);
460 if (!node.two_way) {
461 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 2));
462 dc.SetBrush(*wxCYAN_BRUSH);
463 dc.DrawCircle(item2_pos, 4);
464 dc.SetBrush(*wxTRANSPARENT_BRUSH);
465 }
426 } 466 }
427 } 467 }
428 } 468 }
@@ -543,7 +583,8 @@ void SubwayMap::OnClickHelp(wxCommandEvent &event) {
543 "corner.\nClick on a side of the screen to start panning. It will follow " 583 "corner.\nClick on a side of the screen to start panning. It will follow "
544 "your mouse. Click again to stop.\nHover over a door to see the " 584 "your mouse. Click again to stop.\nHover over a door to see the "
545 "requirements to open it.\nHover over a warp or active painting to see " 585 "requirements to open it.\nHover over a warp or active painting to see "
546 "what it is connected to.\nIn painting shuffle, paintings that have not " 586 "what it is connected to.\nFor one-way connections, there will be a "
587 "circle at the exit.\nIn painting shuffle, paintings that have not "
547 "yet been checked will not show their connections.\nA green shaded owl " 588 "yet been checked will not show their connections.\nA green shaded owl "
548 "means that there is a painting entrance there.\nA red shaded owl means " 589 "means that there is a painting entrance there.\nA red shaded owl means "
549 "that there are only painting exits there.\nClick on a door or " 590 "that there are only painting exits there.\nClick on a door or "
@@ -622,7 +663,7 @@ void SubwayMap::Redraw() {
622 } 663 }
623 } 664 }
624 } 665 }
625 } else if (!subway_item.tags.empty()) { 666 } else if (subway_item.HasWarps()) {
626 draw_type = ItemDrawType::kOwl; 667 draw_type = ItemDrawType::kOwl;
627 } 668 }
628 } else if (subway_door) { 669 } else if (subway_door) {
diff --git a/src/tracker_frame.cpp b/src/tracker_frame.cpp index 3b6beda..b9282f5 100644 --- a/src/tracker_frame.cpp +++ b/src/tracker_frame.cpp
@@ -137,6 +137,7 @@ void TrackerFrame::OnAbout(wxCommandEvent &event) {
137 about_info.SetName("Lingo Archipelago Tracker"); 137 about_info.SetName("Lingo Archipelago Tracker");
138 about_info.SetVersion(kTrackerVersion.ToString()); 138 about_info.SetVersion(kTrackerVersion.ToString());
139 about_info.AddDeveloper("hatkirby"); 139 about_info.AddDeveloper("hatkirby");
140 about_info.AddDeveloper("art0007i");
140 about_info.AddArtist("Brenton Wildes"); 141 about_info.AddArtist("Brenton Wildes");
141 about_info.AddArtist("kinrah"); 142 about_info.AddArtist("kinrah");
142 143
diff --git a/src/version.h b/src/version.h index 24c04b4..ec52f44 100644 --- a/src/version.h +++ b/src/version.h
@@ -36,6 +36,6 @@ struct Version {
36 } 36 }
37}; 37};
38 38
39constexpr const Version kTrackerVersion = Version(0, 11, 1); 39constexpr const Version kTrackerVersion = Version(0, 11, 2);
40 40
41#endif /* end of include guard: VERSION_H_C757E53C */ \ No newline at end of file 41#endif /* end of include guard: VERSION_H_C757E53C */ \ No newline at end of file