about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorart0007i <art0007i@gmail.com>2024-09-24 15:11:32 +0200
committerStar Rauchenberger <fefferburbia@gmail.com>2024-09-24 09:38:26 -0400
commit738d970d26794db8bb3dcf459c4a787b624910ba (patch)
treec5ea9e5eed9ebbab72f5a6cdfc84ca684816001f /src
parent46f46b4caa0fbaba77ac2b2291d908d3bf81dd28 (diff)
downloadlingo-ap-tracker-738d970d26794db8bb3dcf459c4a787b624910ba.tar.gz
lingo-ap-tracker-738d970d26794db8bb3dcf459c4a787b624910ba.tar.bz2
lingo-ap-tracker-738d970d26794db8bb3dcf459c4a787b624910ba.zip
make paintings 1 directional and add "arrows" the "arrows" are circles because I couldn't figure out how to use the DrawPolygon function...
Diffstat (limited to 'src')
-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.cpp80
5 files changed, 113 insertions, 35 deletions
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..c7639ad 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} \ No newline at end of file
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..44f754f 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 }
@@ -622,7 +662,7 @@ void SubwayMap::Redraw() {
622 } 662 }
623 } 663 }
624 } 664 }
625 } else if (!subway_item.tags.empty()) { 665 } else if (subway_item.HasWarps()) {
626 draw_type = ItemDrawType::kOwl; 666 draw_type = ItemDrawType::kOwl;
627 } 667 }
628 } else if (subway_door) { 668 } else if (subway_door) {