about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2023-08-25 22:14:51 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2023-08-25 22:14:51 -0400
commit9bf6a50624284ab7422f56375b3e57c894200faf (patch)
tree9951ee08e5ebbed1363d190b57fa01606e0fbb94
parentbaf43ede759f9ff0ca8c71de764e0389469f9ae1 (diff)
downloadlingo-ap-tracker-9bf6a50624284ab7422f56375b3e57c894200faf.tar.gz
lingo-ap-tracker-9bf6a50624284ab7422f56375b3e57c894200faf.tar.bz2
lingo-ap-tracker-9bf6a50624284ab7422f56375b3e57c894200faf.zip
Panelsanity support
-rwxr-xr-xassets/areas.yaml132
-rw-r--r--src/ap_state.cpp22
-rw-r--r--src/ap_state.h4
-rw-r--r--src/area_popup.cpp23
-rw-r--r--src/area_popup.h2
-rw-r--r--src/game_data.cpp132
-rw-r--r--src/game_data.h8
-rw-r--r--src/tracker_panel.cpp16
8 files changed, 263 insertions, 76 deletions
diff --git a/assets/areas.yaml b/assets/areas.yaml index 501db5a..1df2771 100755 --- a/assets/areas.yaml +++ b/assets/areas.yaml
@@ -9,12 +9,20 @@
9 map: [1589, 1029] 9 map: [1589, 1029]
10 Hub Room: 10 Hub Room:
11 map: [1589, 924] 11 map: [1589, 924]
12 Dead End Area:
13 map: [1785, 1125]
12 Pilgrim Room: 14 Pilgrim Room:
13 map: [1493, 1564] 15 map: [1493, 1564]
16 Pilgrim Antechamber:
17 fold_into: Pilgrim Room
14 Crossroads: 18 Crossroads:
15 map: [1294, 720] 19 map: [1294, 720]
20 Lost Area:
21 fold_into: Crossroads
16 Amen Name Area: 22 Amen Name Area:
17 fold_into: Crossroads 23 fold_into: Crossroads
24 Suits Area:
25 map: [1566, 322]
18 The Tenacious: 26 The Tenacious:
19 map: [1589, 780] 27 map: [1589, 780]
20 Warts Straw Area: 28 Warts Straw Area:
@@ -25,6 +33,12 @@
25 map: [1766, 700] 33 map: [1766, 700]
26 Hallway Room: 34 Hallway Room:
27 map: [573, 1631] 35 map: [573, 1631]
36 Hallway Room (2):
37 fold_into: Hallway Room
38 Hallway Room (3):
39 fold_into: Hallway Room
40 Hallway Room (4):
41 fold_into: Hallway Room
28 Dread Hallway: 42 Dread Hallway:
29 fold_into: Outside The Agreeable 43 fold_into: Outside The Agreeable
30 The Agreeable: 44 The Agreeable:
@@ -35,10 +49,16 @@
35 map: [2251, 600] 49 map: [2251, 600]
36 The Fearless: 50 The Fearless:
37 map: [1790, 2220] 51 map: [1790, 2220]
52 The Fearless (First Floor):
53 fold_into: The Fearless
54 The Fearless (Second Floor):
55 fold_into: The Fearless
38 The Observant: 56 The Observant:
39 map: [2252, 193] 57 map: [2252, 193]
40 The Incomparable: 58 The Incomparable:
41 map: [2642, 872] 59 map: [2642, 872]
60 Eight Room:
61 fold_into: The Incomparable
42 Orange Tower First Floor: 62 Orange Tower First Floor:
43 map: [1285, 928] 63 map: [1285, 928]
44 Color Hunt: 64 Color Hunt:
@@ -47,6 +67,8 @@
47 map: [1935, 1575] 67 map: [1935, 1575]
48 Orange Tower Fourth Floor: 68 Orange Tower Fourth Floor:
49 map: [1365, 394] 69 map: [1365, 394]
70 Hot Crusts Area:
71 fold_into: Orange Tower Fourth Floor
50 Orange Tower Fifth Floor: 72 Orange Tower Fifth Floor:
51 map: [1252, 1259] 73 map: [1252, 1259]
52 Orange Tower Seventh Floor: 74 Orange Tower Seventh Floor:
@@ -55,8 +77,32 @@
55 map: [1587, 2000] 77 map: [1587, 2000]
56 Courtyard: 78 Courtyard:
57 map: [863, 387] 79 map: [863, 387]
80 First Second Third Fourth:
81 fold_into: Courtyard
82 Yellow Backside Area:
83 fold_into: Courtyard
58 The Colorful: 84 The Colorful:
59 map: [863, 200] 85 map: [863, 200]
86 The Colorful (Black):
87 fold_into: The Colorful
88 The Colorful (Blue):
89 fold_into: The Colorful
90 The Colorful (Brown):
91 fold_into: The Colorful
92 The Colorful (Gray):
93 fold_into: The Colorful
94 The Colorful (Green):
95 fold_into: The Colorful
96 The Colorful (Orange):
97 fold_into: The Colorful
98 The Colorful (Purple):
99 fold_into: The Colorful
100 The Colorful (Red):
101 fold_into: The Colorful
102 The Colorful (White):
103 fold_into: The Colorful
104 The Colorful (Yellow):
105 fold_into: The Colorful
60 Welcome Back Area: 106 Welcome Back Area:
61 map: [1472, 1233] 107 map: [1472, 1233]
62 Owl Hallway: 108 Owl Hallway:
@@ -85,24 +131,96 @@
85 map: [1845, 1883] 131 map: [1845, 1883]
86 The Bearer: 132 The Bearer:
87 map: [2155, 1764] 133 map: [2155, 1764]
134 Bearer Side Area:
135 fold_into: The Bearer
136 The Bearer (East):
137 fold_into: The Bearer
138 The Bearer (North):
139 fold_into: The Bearer
140 The Bearer (South):
141 fold_into: The Bearer
142 The Bearer (West):
143 fold_into: The Bearer
88 The Steady: 144 The Steady:
89 map: [2121, 2182] 145 map: [2121, 2182]
146 The Steady (Amber):
147 fold_into: The Steady
148 The Steady (Amethyst):
149 fold_into: The Steady
150 The Steady (Blueberry):
151 fold_into: The Steady
152 The Steady (Carnation):
153 fold_into: The Steady
154 The Steady (Cherry):
155 fold_into: The Steady
156 The Steady (Emerald):
157 fold_into: The Steady
158 The Steady (Lemon):
159 fold_into: The Steady
160 The Steady (Lilac):
161 fold_into: The Steady
162 The Steady (Lime):
163 fold_into: The Steady
164 The Steady (Orange):
165 fold_into: The Steady
166 The Steady (Plum):
167 fold_into: The Steady
168 The Steady (Rose):
169 fold_into: The Steady
170 The Steady (Ruby):
171 fold_into: The Steady
172 The Steady (Sapphire):
173 fold_into: The Steady
174 The Steady (Sunflower):
175 fold_into: The Steady
176 The Steady (Topaz):
177 fold_into: The Steady
90 Knight Night Room: 178 Knight Night Room:
91 map: [1990, 1322] 179 map: [1990, 1322]
180 Knight Night (Final):
181 fold_into: Knight Night Room
182 Knight Night (Outer Ring):
183 fold_into: Knight Night Room
184 Knight Night (Right Lower Segment):
185 fold_into: Knight Night Room
186 Knight Night (Right Upper Segment):
187 fold_into: Knight Night Room
188 Knight Night Exit:
189 fold_into: Knight Night Room
92 The Artistic: 190 The Artistic:
93 map: [1151, 1793] 191 map: [1151, 1793]
94 The Artistic (Smiley): 192 The Artistic (Smiley):
95 fold_into: The Artistic 193 fold_into: The Artistic
194 The Artistic (Apple):
195 fold_into: The Artistic
196 The Artistic (Hint Room):
197 fold_into: The Artistic
198 The Artistic (Lattice):
199 fold_into: The Artistic
200 The Artistic (Panda):
201 fold_into: The Artistic
96 The Discerning: 202 The Discerning:
97 map: [1098, 807] 203 map: [1098, 807]
98 The Ecstatic: 204 The Ecstatic:
99 map: [972, 805] 205 map: [972, 805]
100 The Eyes They See: 206 The Eyes They See:
101 map: [955, 933] 207 map: [955, 933]
208 Far Window:
209 fold_into: The Eyes They See
102 Outside The Wondrous: 210 Outside The Wondrous:
103 map: [691, 524] 211 map: [691, 524]
104 The Wondrous: 212 The Wondrous:
105 map: [648, 338] 213 map: [648, 338]
214 The Wondrous (Bookcase):
215 fold_into: The Wondrous
216 The Wondrous (Chandelier):
217 fold_into: The Wondrous
218 The Wondrous (Table):
219 fold_into: The Wondrous
220 The Wondrous (Window):
221 fold_into: The Wondrous
222 Arrow Garden:
223 map: [555, 155]
106 Elements Area: 224 Elements Area:
107 map: [908, 1632] 225 map: [908, 1632]
108 The Wanderer: 226 The Wanderer:
@@ -117,8 +235,14 @@
117 map: [1587, 1492] 235 map: [1587, 1492]
118 Rhyme Room (Target): 236 Rhyme Room (Target):
119 fold_into: Rhyme Room 237 fold_into: Rhyme Room
238 Rhyme Room (Circle):
239 fold_into: Rhyme Room
240 Rhyme Room (Looped Square):
241 fold_into: Rhyme Room
120 Room Room: 242 Room Room:
121 map: [2553, 2153] 243 map: [2553, 2153]
244 Cellar:
245 fold_into: Room Room
122 Outside The Wise: 246 Outside The Wise:
123 map: [1087, 1986] 247 map: [1087, 1986]
124 The Wise: 248 The Wise:
@@ -129,5 +253,13 @@
129 map: [1368, 2103] 253 map: [1368, 2103]
130 Art Gallery: 254 Art Gallery:
131 map: [2474, 1366] 255 map: [2474, 1366]
256 Art Gallery (Second Floor):
257 fold_into: Art Gallery
258 Art Gallery (Third Floor):
259 fold_into: Art Gallery
260 Art Gallery (Fourth Floor):
261 fold_into: Art Gallery
132 Challenge Room: 262 Challenge Room:
133 map: [1486, 1357] 263 map: [1486, 1357]
264 Roof:
265 map: [227, 1271]
diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 02f1f5a..ced4f83 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp
@@ -62,7 +62,7 @@ struct APState {
62 bool painting_shuffle = false; 62 bool painting_shuffle = false;
63 int mastery_requirement = 21; 63 int mastery_requirement = 21;
64 int level_2_requirement = 223; 64 int level_2_requirement = 223;
65 bool reduce_checks = false; 65 LocationChecks location_checks = kNORMAL_LOCATIONS;
66 VictoryCondition victory_condition = kTHE_END; 66 VictoryCondition victory_condition = kTHE_END;
67 67
68 std::map<std::string, std::string> painting_mapping; 68 std::map<std::string, std::string> painting_mapping;
@@ -122,7 +122,7 @@ struct APState {
122 painting_mapping.clear(); 122 painting_mapping.clear();
123 mastery_requirement = 21; 123 mastery_requirement = 21;
124 level_2_requirement = 223; 124 level_2_requirement = 223;
125 reduce_checks = false; 125 location_checks = kNORMAL_LOCATIONS;
126 victory_condition = kTHE_END; 126 victory_condition = kTHE_END;
127 127
128 connected = false; 128 connected = false;
@@ -209,12 +209,11 @@ struct APState {
209 data_storage_prefix = 209 data_storage_prefix =
210 "Lingo_" + std::to_string(apclient->get_player_number()) + "_"; 210 "Lingo_" + std::to_string(apclient->get_player_number()) + "_";
211 door_shuffle_mode = slot_data["shuffle_doors"].get<DoorShuffleMode>(); 211 door_shuffle_mode = slot_data["shuffle_doors"].get<DoorShuffleMode>();
212 color_shuffle = slot_data["shuffle_colors"].get<bool>(); 212 color_shuffle = slot_data["shuffle_colors"].get<int>() == 1;
213 painting_shuffle = slot_data["shuffle_paintings"].get<bool>(); 213 painting_shuffle = slot_data["shuffle_paintings"].get<int>() == 1;
214 mastery_requirement = slot_data["mastery_achievements"].get<int>(); 214 mastery_requirement = slot_data["mastery_achievements"].get<int>();
215 level_2_requirement = slot_data["level_2_requirement"].get<int>(); 215 level_2_requirement = slot_data["level_2_requirement"].get<int>();
216 reduce_checks = (door_shuffle_mode == kNO_DOORS) && 216 location_checks = slot_data["location_checks"].get<LocationChecks>();
217 slot_data["reduce_checks"].get<bool>();
218 victory_condition = 217 victory_condition =
219 slot_data["victory_condition"].get<VictoryCondition>(); 218 slot_data["victory_condition"].get<VictoryCondition>();
220 219
@@ -444,7 +443,16 @@ int AP_GetMasteryRequirement() { return GetState().mastery_requirement; }
444 443
445int AP_GetLevel2Requirement() { return GetState().level_2_requirement; } 444int AP_GetLevel2Requirement() { return GetState().level_2_requirement; }
446 445
447bool AP_IsReduceChecks() { return GetState().reduce_checks; } 446bool AP_IsLocationVisible(int classification) {
447 switch (GetState().location_checks) {
448 case kNORMAL_LOCATIONS:
449 return classification & kLOCATION_NORMAL;
450 case kREDUCED_LOCATIONS:
451 return classification & kLOCATION_REDUCED;
452 case kPANELSANITY:
453 return classification & kLOCATION_INSANITY;
454 }
455}
448 456
449VictoryCondition AP_GetVictoryCondition() { 457VictoryCondition AP_GetVictoryCondition() {
450 return GetState().victory_condition; 458 return GetState().victory_condition;
diff --git a/src/ap_state.h b/src/ap_state.h index fb5c969..e9b9f92 100644 --- a/src/ap_state.h +++ b/src/ap_state.h
@@ -12,6 +12,8 @@ enum DoorShuffleMode { kNO_DOORS = 0, kSIMPLE_DOORS = 1, kCOMPLEX_DOORS = 2 };
12 12
13enum VictoryCondition { kTHE_END = 0, kTHE_MASTER = 1, kLEVEL_2 = 2 }; 13enum VictoryCondition { kTHE_END = 0, kTHE_MASTER = 1, kLEVEL_2 = 2 };
14 14
15enum LocationChecks { kNORMAL_LOCATIONS = 0, kREDUCED_LOCATIONS = 1, kPANELSANITY = 2 };
16
15void AP_SetTrackerFrame(TrackerFrame* tracker_frame); 17void AP_SetTrackerFrame(TrackerFrame* tracker_frame);
16 18
17void AP_Connect(std::string server, std::string player, std::string password); 19void AP_Connect(std::string server, std::string player, std::string password);
@@ -34,7 +36,7 @@ int AP_GetMasteryRequirement();
34 36
35int AP_GetLevel2Requirement(); 37int AP_GetLevel2Requirement();
36 38
37bool AP_IsReduceChecks(); 39bool AP_IsLocationVisible(int classification);
38 40
39VictoryCondition AP_GetVictoryCondition(); 41VictoryCondition AP_GetVictoryCondition();
40 42
diff --git a/src/area_popup.cpp b/src/area_popup.cpp index a3ac588..28554d0 100644 --- a/src/area_popup.cpp +++ b/src/area_popup.cpp
@@ -5,7 +5,7 @@
5#include "tracker_state.h" 5#include "tracker_state.h"
6 6
7AreaPopup::AreaPopup(wxWindow* parent, int area_id) 7AreaPopup::AreaPopup(wxWindow* parent, int area_id)
8 : wxPanel(parent, wxID_ANY), area_id_(area_id) { 8 : wxScrolledWindow(parent, wxID_ANY), area_id_(area_id) {
9 const MapArea& map_area = GD_GetMapArea(area_id); 9 const MapArea& map_area = GD_GetMapArea(area_id);
10 10
11 wxFlexGridSizer* section_sizer = new wxFlexGridSizer(2, 10, 10); 11 wxFlexGridSizer* section_sizer = new wxFlexGridSizer(2, 10, 10);
@@ -34,6 +34,7 @@ AreaPopup::AreaPopup(wxWindow* parent, int area_id)
34 top_sizer->Add(section_sizer, wxSizerFlags().DoubleBorder(wxALL).Expand()); 34 top_sizer->Add(section_sizer, wxSizerFlags().DoubleBorder(wxALL).Expand());
35 35
36 SetSizerAndFit(top_sizer); 36 SetSizerAndFit(top_sizer);
37 SetScrollRate(5, 5);
37 38
38 SetBackgroundColour(*wxBLACK); 39 SetBackgroundColour(*wxBLACK);
39 Hide(); 40 Hide();
@@ -44,18 +45,16 @@ void AreaPopup::UpdateIndicators() {
44 for (int section_id = 0; section_id < map_area.locations.size(); 45 for (int section_id = 0; section_id < map_area.locations.size();
45 section_id++) { 46 section_id++) {
46 const Location& location = map_area.locations.at(section_id); 47 const Location& location = map_area.locations.at(section_id);
47 if (location.exclude_reduce) { 48 wxSizer* container_sizer =
48 wxSizer* container_sizer = 49 section_labels_[section_id]->GetContainingSizer();
49 section_labels_[section_id]->GetContainingSizer();
50 50
51 if (AP_IsReduceChecks()) { 51 if (!AP_IsLocationVisible(location.classification)) {
52 container_sizer->Hide(section_labels_[section_id]); 52 container_sizer->Hide(section_labels_[section_id]);
53 container_sizer->Hide(eye_indicators_[section_id]); 53 container_sizer->Hide(eye_indicators_[section_id]);
54 continue; 54 continue;
55 } else { 55 } else {
56 container_sizer->Show(section_labels_[section_id]); 56 container_sizer->Show(section_labels_[section_id]);
57 container_sizer->Show(eye_indicators_[section_id]); 57 container_sizer->Show(eye_indicators_[section_id]);
58 }
59 } 58 }
60 59
61 bool checked = AP_HasCheckedGameLocation(area_id_, section_id); 60 bool checked = AP_HasCheckedGameLocation(area_id_, section_id);
diff --git a/src/area_popup.h b/src/area_popup.h index b602b63..d5f6a50 100644 --- a/src/area_popup.h +++ b/src/area_popup.h
@@ -9,7 +9,7 @@
9 9
10#include "eye_indicator.h" 10#include "eye_indicator.h"
11 11
12class AreaPopup : public wxPanel { 12class AreaPopup : public wxScrolledWindow {
13 public: 13 public:
14 AreaPopup(wxWindow* parent, int area_id); 14 AreaPopup(wxWindow* parent, int area_id);
15 15
diff --git a/src/game_data.cpp b/src/game_data.cpp index 4393373..06eb80a 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp
@@ -4,6 +4,9 @@
4#include <yaml-cpp/yaml.h> 4#include <yaml-cpp/yaml.h>
5 5
6#include <iostream> 6#include <iostream>
7#include <sstream>
8
9#include "logger.h"
7 10
8namespace { 11namespace {
9 12
@@ -49,6 +52,9 @@ struct GameData {
49 52
50 std::vector<int> achievement_panels_; 53 std::vector<int> achievement_panels_;
51 54
55 bool loaded_area_data_ = false;
56 std::set<std::string> malconfigured_areas_;
57
52 GameData() { 58 GameData() {
53 YAML::Node lingo_config = YAML::LoadFile("assets/LL1.yaml"); 59 YAML::Node lingo_config = YAML::LoadFile("assets/LL1.yaml");
54 YAML::Node areas_config = YAML::LoadFile("assets/areas.yaml"); 60 YAML::Node areas_config = YAML::LoadFile("assets/areas.yaml");
@@ -179,7 +185,8 @@ struct GameData {
179 if (panel_it.second["required_panel"].IsMap()) { 185 if (panel_it.second["required_panel"].IsMap()) {
180 std::string rp_room = room_obj.name; 186 std::string rp_room = room_obj.name;
181 if (panel_it.second["required_panel"]["room"]) { 187 if (panel_it.second["required_panel"]["room"]) {
182 rp_room = panel_it.second["required_panel"]["room"].as<std::string>(); 188 rp_room =
189 panel_it.second["required_panel"]["room"].as<std::string>();
183 } 190 }
184 191
185 panel_obj.required_panels.push_back(AddOrGetPanel( 192 panel_obj.required_panels.push_back(AddOrGetPanel(
@@ -204,7 +211,8 @@ struct GameData {
204 211
205 if (panel_it.second["achievement"]) { 212 if (panel_it.second["achievement"]) {
206 panel_obj.achievement = true; 213 panel_obj.achievement = true;
207 panel_obj.achievement_name = panel_it.second["achievement"].as<std::string>(); 214 panel_obj.achievement_name =
215 panel_it.second["achievement"].as<std::string>();
208 216
209 achievement_panels_.push_back(panel_id); 217 achievement_panels_.push_back(panel_id);
210 } 218 }
@@ -356,71 +364,88 @@ struct GameData {
356 } 364 }
357 } 365 }
358 366
367 loaded_area_data_ = true;
368
369 // Only locations for the panels are kept here.
370 std::map<std::string, std::tuple<int, int>> locations_by_name;
371
359 for (const Panel &panel : panels_) { 372 for (const Panel &panel : panels_) {
360 if (panel.check) { 373 int room_id = panel.room;
361 int room_id = panel.room; 374 std::string room_name = rooms_[room_id].name;
362 std::string room_name = rooms_[room_id].name;
363 375
364 std::string area_name = room_name; 376 std::string area_name = room_name;
365 if (fold_areas.count(room_name)) { 377 if (fold_areas.count(room_name)) {
366 int fold_area_id = fold_areas[room_name]; 378 int fold_area_id = fold_areas[room_name];
367 area_name = map_areas_[fold_area_id].name; 379 area_name = map_areas_[fold_area_id].name;
368 } 380 }
369 381
370 int area_id = AddOrGetArea(area_name); 382 int classification = kLOCATION_INSANITY;
371 MapArea &map_area = map_areas_[area_id]; 383 if (panel.check) {
372 // room field should be the original room ID 384 classification |= kLOCATION_NORMAL;
373 map_area.locations.push_back( 385 if (!panel.exclude_reduce) {
374 {.name = panel.name, 386 classification |= kLOCATION_REDUCED;
375 .ap_location_name = room_name + " - " + panel.name, 387 }
376 .room = panel.room,
377 .panels = {panel.id},
378 .exclude_reduce = panel.exclude_reduce});
379 } 388 }
389
390 int area_id = AddOrGetArea(area_name);
391 MapArea &map_area = map_areas_[area_id];
392 // room field should be the original room ID
393 map_area.locations.push_back(
394 {.name = panel.name,
395 .ap_location_name = room_name + " - " + panel.name,
396 .room = panel.room,
397 .panels = {panel.id},
398 .classification = classification});
399 locations_by_name[map_area.locations.back().ap_location_name] = {
400 area_id, map_area.locations.size() - 1};
380 } 401 }
381 402
382 for (int door_id : door_definition_order_) { 403 for (int door_id : door_definition_order_) {
383 const Door &door = doors_.at(door_id); 404 const Door &door = doors_.at(door_id);
384 405
385 if (!door.skip_location) { 406 if (!door.skip_location) {
386 int room_id = door.room; 407 int classification = kLOCATION_NORMAL;
387 std::string area_name = rooms_[room_id].name; 408 if (!door.exclude_reduce) {
388 std::string section_name; 409 classification |= kLOCATION_REDUCED;
410 }
389 411
390 size_t divider_pos = door.location_name.find(" - "); 412 if (locations_by_name.count(door.location_name)) {
391 if (divider_pos == std::string::npos) { 413 auto [area_id, section_id] = locations_by_name[door.location_name];
392 section_name = door.location_name; 414 map_areas_[area_id].locations[section_id].classification |=
415 classification;
393 } else { 416 } else {
394 area_name = door.location_name.substr(0, divider_pos); 417 int room_id = door.room;
395 section_name = door.location_name.substr(divider_pos + 3); 418 std::string area_name = rooms_[room_id].name;
396 } 419 std::string section_name;
420
421 size_t divider_pos = door.location_name.find(" - ");
422 if (divider_pos == std::string::npos) {
423 section_name = door.location_name;
424 } else {
425 area_name = door.location_name.substr(0, divider_pos);
426 section_name = door.location_name.substr(divider_pos + 3);
427 }
397 428
398 if (fold_areas.count(area_name)) { 429 if (fold_areas.count(area_name)) {
399 int fold_area_id = fold_areas[area_name]; 430 int fold_area_id = fold_areas[area_name];
400 area_name = map_areas_[fold_area_id].name; 431 area_name = map_areas_[fold_area_id].name;
401 } 432 }
402 433
403 int area_id = AddOrGetArea(area_name); 434 int area_id = AddOrGetArea(area_name);
404 MapArea &map_area = map_areas_[area_id]; 435 MapArea &map_area = map_areas_[area_id];
405 // room field should be the original room ID 436 // room field should be the original room ID
406 map_area.locations.push_back({.name = section_name, 437 map_area.locations.push_back({.name = section_name,
407 .ap_location_name = door.location_name, 438 .ap_location_name = door.location_name,
408 .room = door.room, 439 .room = door.room,
409 .panels = door.panels, 440 .panels = door.panels,
410 .exclude_reduce = door.exclude_reduce}); 441 .classification = classification});
442 }
411 } 443 }
412 } 444 }
413 445
414 for (MapArea &map_area : map_areas_) { 446 for (MapArea &map_area : map_areas_) {
415 bool all_exclude_reduce = true;
416 for (const Location &location : map_area.locations) { 447 for (const Location &location : map_area.locations) {
417 if (!location.exclude_reduce) { 448 map_area.classification |= location.classification;
418 all_exclude_reduce = false;
419 break;
420 }
421 }
422 if (all_exclude_reduce) {
423 map_area.exclude_reduce = true;
424 } 449 }
425 } 450 }
426 451
@@ -450,6 +475,13 @@ struct GameData {
450 starting_room_obj.exits.push_back( 475 starting_room_obj.exits.push_back(
451 Exit{.destination_room = AddOrGetRoom("Pilgrim Antechamber"), 476 Exit{.destination_room = AddOrGetRoom("Pilgrim Antechamber"),
452 .door = fake_pilgrim_door_id}); 477 .door = fake_pilgrim_door_id});
478
479 // Report errors.
480 for (const std::string &area : malconfigured_areas_) {
481 std::ostringstream errstr;
482 errstr << "Area data not found for: " << area;
483 TrackerLog(errstr.str());
484 }
453 } 485 }
454 486
455 int AddOrGetRoom(std::string room) { 487 int AddOrGetRoom(std::string room) {
@@ -487,6 +519,10 @@ struct GameData {
487 519
488 int AddOrGetArea(std::string area) { 520 int AddOrGetArea(std::string area) {
489 if (!area_by_id_.count(area)) { 521 if (!area_by_id_.count(area)) {
522 if (loaded_area_data_) {
523 malconfigured_areas_.insert(area);
524 }
525
490 int area_id = map_areas_.size(); 526 int area_id = map_areas_.size();
491 area_by_id_[area] = area_id; 527 area_by_id_[area] = area_id;
492 map_areas_.push_back({.id = area_id, .name = area}); 528 map_areas_.push_back({.id = area_id, .name = area});
diff --git a/src/game_data.h b/src/game_data.h index 959d5c8..d9c909b 100644 --- a/src/game_data.h +++ b/src/game_data.h
@@ -19,6 +19,10 @@ enum class LingoColor {
19 kGray 19 kGray
20}; 20};
21 21
22constexpr int kLOCATION_NORMAL = 1;
23constexpr int kLOCATION_REDUCED = 2;
24constexpr int kLOCATION_INSANITY = 4;
25
22struct Panel { 26struct Panel {
23 int id; 27 int id;
24 int room; 28 int room;
@@ -76,7 +80,7 @@ struct Location {
76 std::string ap_location_name; 80 std::string ap_location_name;
77 int room; 81 int room;
78 std::vector<int> panels; 82 std::vector<int> panels;
79 bool exclude_reduce = false; 83 int classification = 0;
80}; 84};
81 85
82struct MapArea { 86struct MapArea {
@@ -85,7 +89,7 @@ struct MapArea {
85 std::vector<Location> locations; 89 std::vector<Location> locations;
86 int map_x; 90 int map_x;
87 int map_y; 91 int map_y;
88 bool exclude_reduce = false; 92 int classification = 0;
89}; 93};
90 94
91const std::vector<MapArea>& GD_GetMapAreas(); 95const std::vector<MapArea>& GD_GetMapAreas();
diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index 90b8eb9..40d3ced 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp
@@ -52,9 +52,9 @@ void TrackerPanel::OnPaint(wxPaintEvent &event) {
52 52
53void TrackerPanel::OnMouseMove(wxMouseEvent &event) { 53void TrackerPanel::OnMouseMove(wxMouseEvent &event) {
54 for (AreaIndicator &area : areas_) { 54 for (AreaIndicator &area : areas_) {
55 if (area.active && 55 if (area.active && area.real_x1 <= event.GetX() &&
56 area.real_x1 <= event.GetX() && event.GetX() < area.real_x2 && 56 event.GetX() < area.real_x2 && area.real_y1 <= event.GetY() &&
57 area.real_y1 <= event.GetY() && event.GetY() < area.real_y2) { 57 event.GetY() < area.real_y2) {
58 area.popup->Show(); 58 area.popup->Show();
59 } else { 59 } else {
60 area.popup->Hide(); 60 area.popup->Hide();
@@ -95,7 +95,7 @@ void TrackerPanel::Redraw() {
95 const wxBrush *brush_color = wxGREY_BRUSH; 95 const wxBrush *brush_color = wxGREY_BRUSH;
96 96
97 const MapArea &map_area = GD_GetMapArea(area.area_id); 97 const MapArea &map_area = GD_GetMapArea(area.area_id);
98 if (map_area.exclude_reduce && AP_IsReduceChecks()) { 98 if (!AP_IsLocationVisible(map_area.classification)) {
99 area.active = false; 99 area.active = false;
100 continue; 100 continue;
101 } else { 101 } else {
@@ -106,7 +106,9 @@ void TrackerPanel::Redraw() {
106 bool has_unreachable_unchecked = false; 106 bool has_unreachable_unchecked = false;
107 for (int section_id = 0; section_id < map_area.locations.size(); 107 for (int section_id = 0; section_id < map_area.locations.size();
108 section_id++) { 108 section_id++) {
109 if (!AP_HasCheckedGameLocation(area.area_id, section_id)) { 109 if (AP_IsLocationVisible(
110 map_area.locations.at(section_id).classification) &&
111 !AP_HasCheckedGameLocation(area.area_id, section_id)) {
110 if (IsLocationReachable(area.area_id, section_id)) { 112 if (IsLocationReachable(area.area_id, section_id)) {
111 has_reachable_unchecked = true; 113 has_reachable_unchecked = true;
112 } else { 114 } else {
@@ -146,6 +148,10 @@ void TrackerPanel::Redraw() {
146 final_x + map_area.map_x * final_width / image_size.GetWidth(); 148 final_x + map_area.map_x * final_width / image_size.GetWidth();
147 int popup_y = 149 int popup_y =
148 final_y + map_area.map_y * final_width / image_size.GetWidth(); 150 final_y + map_area.map_y * final_width / image_size.GetWidth();
151
152 area.popup->SetMaxSize(panel_size);
153 area.popup->GetSizer()->Fit(area.popup);
154
149 if (popup_x + area.popup->GetSize().GetWidth() > panel_size.GetWidth()) { 155 if (popup_x + area.popup->GetSize().GetWidth() > panel_size.GetWidth()) {
150 popup_x = panel_size.GetWidth() - area.popup->GetSize().GetWidth(); 156 popup_x = panel_size.GetWidth() - area.popup->GetSize().GetWidth();
151 } 157 }