about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/ap_state.cpp8
-rw-r--r--src/ap_state.h5
-rw-r--r--src/game_data.cpp62
-rw-r--r--src/game_data.h2
-rw-r--r--src/tracker_state.cpp5
5 files changed, 67 insertions, 15 deletions
diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 8ba6633..c1147f6 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp
@@ -261,8 +261,6 @@ struct APState {
261 checked_paintings.count(painting_mapping.at(painting_id))); 261 checked_paintings.count(painting_mapping.at(painting_id)));
262 } 262 }
263 263
264 std::string GetItemName(int id) { return apclient->get_item_name(id, "Lingo"); }
265
266 void RevealPaintings() { 264 void RevealPaintings() {
267 std::lock_guard state_guard(state_mutex); 265 std::lock_guard state_guard(state_mutex);
268 266
@@ -432,7 +430,7 @@ struct APState {
432 } 430 }
433 431
434 for (const auto& [item_id, item_index] : index_by_item) { 432 for (const auto& [item_id, item_index] : index_by_item) {
435 item_states.push_back(ItemState{.name = GetItemName(item_id), 433 item_states.push_back(ItemState{.name = GD_GetItemName(item_id),
436 .amount = inventory[item_id], 434 .amount = inventory[item_id],
437 .index = item_index}); 435 .index = item_index});
438 } 436 }
@@ -743,10 +741,6 @@ bool AP_HasItemSafe(int item_id, int quantity) {
743 return GetState().HasItemSafe(item_id, quantity); 741 return GetState().HasItemSafe(item_id, quantity);
744} 742}
745 743
746std::string AP_GetItemName(int item_id) {
747 return GetState().GetItemName(item_id);
748}
749
750DoorShuffleMode AP_GetDoorShuffleMode() { 744DoorShuffleMode AP_GetDoorShuffleMode() {
751 std::lock_guard state_guard(GetState().state_mutex); 745 std::lock_guard state_guard(GetState().state_mutex);
752 746
diff --git a/src/ap_state.h b/src/ap_state.h index 8641000..54e1187 100644 --- a/src/ap_state.h +++ b/src/ap_state.h
@@ -63,11 +63,6 @@ bool AP_HasItem(int item_id, int quantity = 1);
63 63
64bool AP_HasItemSafe(int item_id, int quantity = 1); 64bool AP_HasItemSafe(int item_id, int quantity = 1);
65 65
66// This doesn't lock the client mutex because it is ONLY to be called from
67// RecalculateReachability, which is only called from within a client callback
68// anyway.
69std::string AP_GetItemName(int item_id);
70
71DoorShuffleMode AP_GetDoorShuffleMode(); 66DoorShuffleMode AP_GetDoorShuffleMode();
72 67
73bool AP_AreDoorsGrouped(); 68bool AP_AreDoorsGrouped();
diff --git a/src/game_data.cpp b/src/game_data.cpp index a5af66b..7ce1fb6 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp
@@ -44,6 +44,8 @@ struct GameData {
44 std::map<std::string, int> subway_item_by_painting_; 44 std::map<std::string, int> subway_item_by_painting_;
45 std::map<SubwaySunwarp, int> subway_item_by_sunwarp_; 45 std::map<SubwaySunwarp, int> subway_item_by_sunwarp_;
46 46
47 std::map<int, std::string> item_by_ap_id_;
48
47 bool loaded_area_data_ = false; 49 bool loaded_area_data_ = false;
48 std::set<std::string> malconfigured_areas_; 50 std::set<std::string> malconfigured_areas_;
49 51
@@ -76,6 +78,14 @@ struct GameData {
76 init_color_id("Brown"); 78 init_color_id("Brown");
77 init_color_id("Gray"); 79 init_color_id("Gray");
78 80
81 if (ids_config["special_items"]) {
82 for (const auto& special_item_it : ids_config["special_items"])
83 {
84 item_by_ap_id_[special_item_it.second.as<int>()] =
85 special_item_it.first.as<std::string>();
86 }
87 }
88
79 rooms_.reserve(lingo_config.size() * 2); 89 rooms_.reserve(lingo_config.size() * 2);
80 90
81 std::vector<int> panel_location_ids; 91 std::vector<int> panel_location_ids;
@@ -339,6 +349,9 @@ struct GameData {
339 ids_config["doors"][rooms_[room_id].name] 349 ids_config["doors"][rooms_[room_id].name]
340 [doors_[door_id].name]["item"] 350 [doors_[door_id].name]["item"]
341 .as<int>(); 351 .as<int>();
352
353 item_by_ap_id_[doors_[door_id].ap_item_id] =
354 doors_[door_id].item_name;
342 } else { 355 } else {
343 TrackerLog(fmt::format("Missing AP item ID for door {} - {}", 356 TrackerLog(fmt::format("Missing AP item ID for door {} - {}",
344 rooms_[room_id].name, 357 rooms_[room_id].name,
@@ -355,6 +368,9 @@ struct GameData {
355 doors_[door_id].group_ap_item_id = 368 doors_[door_id].group_ap_item_id =
356 ids_config["door_groups"][doors_[door_id].group_name] 369 ids_config["door_groups"][doors_[door_id].group_name]
357 .as<int>(); 370 .as<int>();
371
372 item_by_ap_id_[doors_[door_id].group_ap_item_id] =
373 doors_[door_id].group_name;
358 } else { 374 } else {
359 TrackerLog(fmt::format("Missing AP item ID for door group {}", 375 TrackerLog(fmt::format("Missing AP item ID for door group {}",
360 doors_[door_id].group_name)); 376 doors_[door_id].group_name));
@@ -418,21 +434,50 @@ struct GameData {
418 int panel_door_id = 434 int panel_door_id =
419 AddOrGetPanelDoor(rooms_[room_id].name, panel_door_name); 435 AddOrGetPanelDoor(rooms_[room_id].name, panel_door_name);
420 436
437 std::map<std::string, std::vector<std::string>> panel_per_room;
438 int num_panels = 0;
421 for (const auto &panel_node : panel_door_it.second["panels"]) { 439 for (const auto &panel_node : panel_door_it.second["panels"]) {
440 num_panels++;
441
422 int panel_id = -1; 442 int panel_id = -1;
423 443
424 if (panel_node.IsScalar()) { 444 if (panel_node.IsScalar()) {
425 panel_id = AddOrGetPanel(rooms_[room_id].name, 445 panel_id = AddOrGetPanel(rooms_[room_id].name,
426 panel_node.as<std::string>()); 446 panel_node.as<std::string>());
447
448 panel_per_room[rooms_[room_id].name].push_back(
449 panel_node.as<std::string>());
427 } else { 450 } else {
428 panel_id = AddOrGetPanel(panel_node["room"].as<std::string>(), 451 panel_id = AddOrGetPanel(panel_node["room"].as<std::string>(),
429 panel_node["panel"].as<std::string>()); 452 panel_node["panel"].as<std::string>());
453
454 panel_per_room[panel_node["room"].as<std::string>()].push_back(
455 panel_node["panel"].as<std::string>());
430 } 456 }
431 457
432 Panel &panel = panels_[panel_id]; 458 Panel &panel = panels_[panel_id];
433 panel.panel_door = panel_door_id; 459 panel.panel_door = panel_door_id;
434 } 460 }
435 461
462 if (panel_door_it.second["item_name"]) {
463 panel_doors_[panel_door_id].item_name =
464 panel_door_it.second["item_name"].as<std::string>();
465 } else {
466 std::vector<std::string> room_strs;
467 for (const auto &[room_str, panels_str] : panel_per_room) {
468 room_strs.push_back(fmt::format(
469 "{} - {}", room_str, hatkirby::implode(panels_str, ", ")));
470 }
471
472 if (num_panels == 1) {
473 panel_doors_[panel_door_id].item_name =
474 fmt::format("{} (Panel)", room_strs[0]);
475 } else {
476 panel_doors_[panel_door_id].item_name = fmt::format(
477 "{} (Panels)", hatkirby::implode(room_strs, " and "));
478 }
479 }
480
436 if (ids_config["panel_doors"] && 481 if (ids_config["panel_doors"] &&
437 ids_config["panel_doors"][rooms_[room_id].name] && 482 ids_config["panel_doors"][rooms_[room_id].name] &&
438 ids_config["panel_doors"][rooms_[room_id].name] 483 ids_config["panel_doors"][rooms_[room_id].name]
@@ -440,6 +485,9 @@ struct GameData {
440 panel_doors_[panel_door_id].ap_item_id = 485 panel_doors_[panel_door_id].ap_item_id =
441 ids_config["panel_doors"][rooms_[room_id].name][panel_door_name] 486 ids_config["panel_doors"][rooms_[room_id].name][panel_door_name]
442 .as<int>(); 487 .as<int>();
488
489 item_by_ap_id_[panel_doors_[panel_door_id].ap_item_id] =
490 panel_doors_[panel_door_id].item_name;
443 } else { 491 } else {
444 TrackerLog(fmt::format("Missing AP item ID for panel door {} - {}", 492 TrackerLog(fmt::format("Missing AP item ID for panel door {} - {}",
445 rooms_[room_id].name, panel_door_name)); 493 rooms_[room_id].name, panel_door_name));
@@ -453,6 +501,9 @@ struct GameData {
453 ids_config["panel_groups"][panel_group]) { 501 ids_config["panel_groups"][panel_group]) {
454 panel_doors_[panel_door_id].group_ap_item_id = 502 panel_doors_[panel_door_id].group_ap_item_id =
455 ids_config["panel_groups"][panel_group].as<int>(); 503 ids_config["panel_groups"][panel_group].as<int>();
504
505 item_by_ap_id_[panel_doors_[panel_door_id].group_ap_item_id] =
506 panel_group;
456 } else { 507 } else {
457 TrackerLog(fmt::format( 508 TrackerLog(fmt::format(
458 "Missing AP item ID for panel door group {}", panel_group)); 509 "Missing AP item ID for panel door group {}", panel_group));
@@ -516,6 +567,8 @@ struct GameData {
516 ids_config["progression"][progressive_item_name]) { 567 ids_config["progression"][progressive_item_name]) {
517 progressive_item_id = 568 progressive_item_id =
518 ids_config["progression"][progressive_item_name].as<int>(); 569 ids_config["progression"][progressive_item_name].as<int>();
570
571 item_by_ap_id_[progressive_item_id] = progressive_item_name;
519 } else { 572 } else {
520 TrackerLog(fmt::format("Missing AP item ID for progressive item {}", 573 TrackerLog(fmt::format("Missing AP item ID for progressive item {}",
521 progressive_item_name)); 574 progressive_item_name));
@@ -1008,6 +1061,15 @@ int GD_GetSubwayItemForSunwarp(const SubwaySunwarp &sunwarp) {
1008 return GetState().subway_item_by_sunwarp_.at(sunwarp); 1061 return GetState().subway_item_by_sunwarp_.at(sunwarp);
1009} 1062}
1010 1063
1064std::string GD_GetItemName(int id) {
1065 auto it = GetState().item_by_ap_id_.find(id);
1066 if (it != GetState().item_by_ap_id_.end()) {
1067 return it->second;
1068 } else {
1069 return "Unknown";
1070 }
1071}
1072
1011LingoColor GetLingoColorForString(const std::string &str) { 1073LingoColor GetLingoColorForString(const std::string &str) {
1012 if (str == "black") { 1074 if (str == "black") {
1013 return LingoColor::kBlack; 1075 return LingoColor::kBlack;
diff --git a/src/game_data.h b/src/game_data.h index 815ae2e..44084d9 100644 --- a/src/game_data.h +++ b/src/game_data.h
@@ -90,6 +90,7 @@ struct PanelDoor {
90 int ap_item_id = -1; 90 int ap_item_id = -1;
91 int group_ap_item_id = -1; 91 int group_ap_item_id = -1;
92 std::vector<ProgressiveRequirement> progressives; 92 std::vector<ProgressiveRequirement> progressives;
93 std::string item_name;
93}; 94};
94 95
95struct Exit { 96struct Exit {
@@ -190,6 +191,7 @@ const std::vector<SubwayItem>& GD_GetSubwayItems();
190const SubwayItem& GD_GetSubwayItem(int id); 191const SubwayItem& GD_GetSubwayItem(int id);
191std::optional<int> GD_GetSubwayItemForPainting(const std::string& painting_id); 192std::optional<int> GD_GetSubwayItemForPainting(const std::string& painting_id);
192int GD_GetSubwayItemForSunwarp(const SubwaySunwarp& sunwarp); 193int GD_GetSubwayItemForSunwarp(const SubwaySunwarp& sunwarp);
194std::string GD_GetItemName(int id);
193 195
194LingoColor GetLingoColorForString(const std::string& str); 196LingoColor GetLingoColorForString(const std::string& str);
195 197
diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index 40ba6c4..bf2725a 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp
@@ -473,8 +473,7 @@ class StateCalculator {
473 Decision decision = IsNonGroupedDoorReachable(panel_door_obj); 473 Decision decision = IsNonGroupedDoorReachable(panel_door_obj);
474 474
475 if (report) { 475 if (report) {
476 (*report)[AP_GetItemName(panel_door_obj.ap_item_id)] = 476 (*report)[panel_door_obj.item_name] = (decision == kYes);
477 (decision == kYes);
478 } 477 }
479 478
480 if (decision != kYes) { 479 if (decision != kYes) {
@@ -485,7 +484,7 @@ class StateCalculator {
485 for (int item_id : reqs.items) { 484 for (int item_id : reqs.items) {
486 bool has_item = AP_HasItem(item_id); 485 bool has_item = AP_HasItem(item_id);
487 if (report) { 486 if (report) {
488 (*report)[AP_GetItemName(item_id)] = has_item; 487 (*report)[GD_GetItemName(item_id)] = has_item;
489 } 488 }
490 489
491 if (!has_item) { 490 if (!has_item) {