diff options
Diffstat (limited to 'src/game_data.cpp')
| -rw-r--r-- | src/game_data.cpp | 257 |
1 files changed, 202 insertions, 55 deletions
| diff --git a/src/game_data.cpp b/src/game_data.cpp index 0567623..1ccf511 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | #include "game_data.h" | 1 | #include "game_data.h" |
| 2 | 2 | ||
| 3 | #include <wx/wxprec.h> | ||
| 4 | |||
| 5 | #ifndef WX_PRECOMP | ||
| 6 | #include <wx/wx.h> | ||
| 7 | #endif | ||
| 8 | |||
| 3 | #include <hkutil/string.h> | 9 | #include <hkutil/string.h> |
| 4 | #include <yaml-cpp/yaml.h> | 10 | #include <yaml-cpp/yaml.h> |
| 5 | 11 | ||
| @@ -7,7 +13,6 @@ | |||
| 7 | #include <sstream> | 13 | #include <sstream> |
| 8 | 14 | ||
| 9 | #include "global.h" | 15 | #include "global.h" |
| 10 | #include "logger.h" | ||
| 11 | 16 | ||
| 12 | namespace { | 17 | namespace { |
| 13 | 18 | ||
| @@ -31,9 +36,7 @@ LingoColor GetColorForString(const std::string &str) { | |||
| 31 | } else if (str == "purple") { | 36 | } else if (str == "purple") { |
| 32 | return LingoColor::kPurple; | 37 | return LingoColor::kPurple; |
| 33 | } else { | 38 | } else { |
| 34 | std::ostringstream errmsg; | 39 | wxLogError("Invalid color: %s", str); |
| 35 | errmsg << "Invalid color: " << str; | ||
| 36 | TrackerLog(errmsg.str()); | ||
| 37 | 40 | ||
| 38 | return LingoColor::kNone; | 41 | return LingoColor::kNone; |
| 39 | } | 42 | } |
| @@ -45,12 +48,15 @@ struct GameData { | |||
| 45 | std::vector<Panel> panels_; | 48 | std::vector<Panel> panels_; |
| 46 | std::vector<PanelDoor> panel_doors_; | 49 | std::vector<PanelDoor> panel_doors_; |
| 47 | std::vector<MapArea> map_areas_; | 50 | std::vector<MapArea> map_areas_; |
| 51 | std::vector<SubwayItem> subway_items_; | ||
| 52 | std::vector<PaintingExit> paintings_; | ||
| 48 | 53 | ||
| 49 | std::map<std::string, int> room_by_id_; | 54 | std::map<std::string, int> room_by_id_; |
| 50 | std::map<std::string, int> door_by_id_; | 55 | std::map<std::string, int> door_by_id_; |
| 51 | std::map<std::string, int> panel_by_id_; | 56 | std::map<std::string, int> panel_by_id_; |
| 52 | std::map<std::string, int> panel_doors_by_id_; | 57 | std::map<std::string, int> panel_doors_by_id_; |
| 53 | std::map<std::string, int> area_by_id_; | 58 | std::map<std::string, int> area_by_id_; |
| 59 | std::map<std::string, int> painting_by_id_; | ||
| 54 | 60 | ||
| 55 | std::vector<int> door_definition_order_; | 61 | std::vector<int> door_definition_order_; |
| 56 | 62 | ||
| @@ -63,6 +69,9 @@ struct GameData { | |||
| 63 | 69 | ||
| 64 | std::vector<int> sunwarp_doors_; | 70 | std::vector<int> sunwarp_doors_; |
| 65 | 71 | ||
| 72 | std::map<std::string, int> subway_item_by_painting_; | ||
| 73 | std::map<SubwaySunwarp, int> subway_item_by_sunwarp_; | ||
| 74 | |||
| 66 | bool loaded_area_data_ = false; | 75 | bool loaded_area_data_ = false; |
| 67 | std::set<std::string> malconfigured_areas_; | 76 | std::set<std::string> malconfigured_areas_; |
| 68 | 77 | ||
| @@ -81,9 +90,7 @@ struct GameData { | |||
| 81 | ap_id_by_color_[GetColorForString(input_name)] = | 90 | ap_id_by_color_[GetColorForString(input_name)] = |
| 82 | ids_config["special_items"][color_name].as<int>(); | 91 | ids_config["special_items"][color_name].as<int>(); |
| 83 | } else { | 92 | } else { |
| 84 | std::ostringstream errmsg; | 93 | wxLogError("Missing AP item ID for color %s", color_name); |
| 85 | errmsg << "Missing AP item ID for color " << color_name; | ||
| 86 | TrackerLog(errmsg.str()); | ||
| 87 | } | 94 | } |
| 88 | }; | 95 | }; |
| 89 | 96 | ||
| @@ -158,8 +165,9 @@ struct GameData { | |||
| 158 | } | 165 | } |
| 159 | default: { | 166 | default: { |
| 160 | // This shouldn't happen. | 167 | // This shouldn't happen. |
| 161 | std::cout << "Error reading game data: " << entrance_it | 168 | std::ostringstream formatted; |
| 162 | << std::endl; | 169 | formatted << entrance_it; |
| 170 | wxLogError("Error reading game data: %s", formatted.str()); | ||
| 163 | break; | 171 | break; |
| 164 | } | 172 | } |
| 165 | } | 173 | } |
| @@ -256,6 +264,11 @@ struct GameData { | |||
| 256 | achievement_panels_.push_back(panel_id); | 264 | achievement_panels_.push_back(panel_id); |
| 257 | } | 265 | } |
| 258 | 266 | ||
| 267 | if (panel_it.second["location_name"]) { | ||
| 268 | panels_[panel_id].location_name = | ||
| 269 | panel_it.second["location_name"].as<std::string>(); | ||
| 270 | } | ||
| 271 | |||
| 259 | if (panel_it.second["hunt"]) { | 272 | if (panel_it.second["hunt"]) { |
| 260 | panels_[panel_id].hunt = panel_it.second["hunt"].as<bool>(); | 273 | panels_[panel_id].hunt = panel_it.second["hunt"].as<bool>(); |
| 261 | } | 274 | } |
| @@ -279,10 +292,8 @@ struct GameData { | |||
| 279 | [panels_[panel_id].name] | 292 | [panels_[panel_id].name] |
| 280 | .as<int>(); | 293 | .as<int>(); |
| 281 | } else { | 294 | } else { |
| 282 | std::ostringstream errmsg; | 295 | wxLogError("Missing AP location ID for panel %s - %s", |
| 283 | errmsg << "Missing AP location ID for panel " | 296 | rooms_[room_id].name, panels_[panel_id].name); |
| 284 | << rooms_[room_id].name << " - " << panels_[panel_id].name; | ||
| 285 | TrackerLog(errmsg.str()); | ||
| 286 | } | 297 | } |
| 287 | } | 298 | } |
| 288 | } | 299 | } |
| @@ -345,10 +356,8 @@ struct GameData { | |||
| 345 | [doors_[door_id].name]["item"] | 356 | [doors_[door_id].name]["item"] |
| 346 | .as<int>(); | 357 | .as<int>(); |
| 347 | } else { | 358 | } else { |
| 348 | std::ostringstream errmsg; | 359 | wxLogError("Missing AP item ID for door %s - %s", |
| 349 | errmsg << "Missing AP item ID for door " << rooms_[room_id].name | 360 | rooms_[room_id].name, doors_[door_id].name); |
| 350 | << " - " << doors_[door_id].name; | ||
| 351 | TrackerLog(errmsg.str()); | ||
| 352 | } | 361 | } |
| 353 | } | 362 | } |
| 354 | 363 | ||
| @@ -362,10 +371,8 @@ struct GameData { | |||
| 362 | ids_config["door_groups"][doors_[door_id].group_name] | 371 | ids_config["door_groups"][doors_[door_id].group_name] |
| 363 | .as<int>(); | 372 | .as<int>(); |
| 364 | } else { | 373 | } else { |
| 365 | std::ostringstream errmsg; | 374 | wxLogError("Missing AP item ID for door group %s", |
| 366 | errmsg << "Missing AP item ID for door group " | 375 | doors_[door_id].group_name); |
| 367 | << doors_[door_id].group_name; | ||
| 368 | TrackerLog(errmsg.str()); | ||
| 369 | } | 376 | } |
| 370 | } | 377 | } |
| 371 | 378 | ||
| @@ -375,13 +382,11 @@ struct GameData { | |||
| 375 | } else if (!door_it.second["skip_location"] && | 382 | } else if (!door_it.second["skip_location"] && |
| 376 | !door_it.second["event"]) { | 383 | !door_it.second["event"]) { |
| 377 | if (has_external_panels) { | 384 | if (has_external_panels) { |
| 378 | std::ostringstream errmsg; | 385 | wxLogError( |
| 379 | errmsg | 386 | "%s - %s has panels from other rooms but does not have an " |
| 380 | << rooms_[room_id].name << " - " << doors_[door_id].name | 387 | "explicit location name and is not marked skip_location or " |
| 381 | << " has panels from other rooms but does not have an " | 388 | "event", |
| 382 | "explicit " | 389 | rooms_[room_id].name, doors_[door_id].name); |
| 383 | "location name and is not marked skip_location or event"; | ||
| 384 | TrackerLog(errmsg.str()); | ||
| 385 | } | 390 | } |
| 386 | 391 | ||
| 387 | doors_[door_id].location_name = | 392 | doors_[door_id].location_name = |
| @@ -401,10 +406,8 @@ struct GameData { | |||
| 401 | [doors_[door_id].name]["location"] | 406 | [doors_[door_id].name]["location"] |
| 402 | .as<int>(); | 407 | .as<int>(); |
| 403 | } else { | 408 | } else { |
| 404 | std::ostringstream errmsg; | 409 | wxLogError("Missing AP location ID for door %s - %s", |
| 405 | errmsg << "Missing AP location ID for door " | 410 | rooms_[room_id].name, doors_[door_id].name); |
| 406 | << rooms_[room_id].name << " - " << doors_[door_id].name; | ||
| 407 | TrackerLog(errmsg.str()); | ||
| 408 | } | 411 | } |
| 409 | } | 412 | } |
| 410 | 413 | ||
| @@ -478,12 +481,14 @@ struct GameData { | |||
| 478 | 481 | ||
| 479 | if (room_it.second["paintings"]) { | 482 | if (room_it.second["paintings"]) { |
| 480 | for (const auto &painting : room_it.second["paintings"]) { | 483 | for (const auto &painting : room_it.second["paintings"]) { |
| 481 | std::string painting_id = painting["id"].as<std::string>(); | 484 | std::string internal_id = painting["id"].as<std::string>(); |
| 482 | room_by_painting_[painting_id] = room_id; | 485 | int painting_id = AddOrGetPainting(internal_id); |
| 486 | PaintingExit &painting_exit = paintings_[painting_id]; | ||
| 487 | painting_exit.room = room_id; | ||
| 483 | 488 | ||
| 484 | if (!painting["exit_only"] || !painting["exit_only"].as<bool>()) { | 489 | if ((!painting["exit_only"] || !painting["exit_only"].as<bool>()) && |
| 485 | PaintingExit painting_exit; | 490 | (!painting["disable"] || !painting["disable"].as<bool>())) { |
| 486 | painting_exit.id = painting_id; | 491 | painting_exit.entrance = true; |
| 487 | 492 | ||
| 488 | if (painting["required_door"]) { | 493 | if (painting["required_door"]) { |
| 489 | std::string rd_room = rooms_[room_id].name; | 494 | std::string rd_room = rooms_[room_id].name; |
| @@ -494,9 +499,9 @@ struct GameData { | |||
| 494 | painting_exit.door = AddOrGetDoor( | 499 | painting_exit.door = AddOrGetDoor( |
| 495 | rd_room, painting["required_door"]["door"].as<std::string>()); | 500 | rd_room, painting["required_door"]["door"].as<std::string>()); |
| 496 | } | 501 | } |
| 497 | |||
| 498 | rooms_[room_id].paintings.push_back(painting_exit); | ||
| 499 | } | 502 | } |
| 503 | |||
| 504 | rooms_[room_id].paintings.push_back(painting_exit.id); | ||
| 500 | } | 505 | } |
| 501 | } | 506 | } |
| 502 | 507 | ||
| @@ -523,10 +528,8 @@ struct GameData { | |||
| 523 | progressive_item_id = | 528 | progressive_item_id = |
| 524 | ids_config["progression"][progressive_item_name].as<int>(); | 529 | ids_config["progression"][progressive_item_name].as<int>(); |
| 525 | } else { | 530 | } else { |
| 526 | std::ostringstream errmsg; | 531 | wxLogError("Missing AP item ID for progressive item %s", |
| 527 | errmsg << "Missing AP item ID for progressive item " | 532 | progressive_item_name); |
| 528 | << progressive_item_name; | ||
| 529 | TrackerLog(errmsg.str()); | ||
| 530 | } | 533 | } |
| 531 | 534 | ||
| 532 | if (progression_it.second["doors"]) { | 535 | if (progression_it.second["doors"]) { |
| @@ -600,8 +603,21 @@ struct GameData { | |||
| 600 | std::string room_name = rooms_[room_id].name; | 603 | std::string room_name = rooms_[room_id].name; |
| 601 | 604 | ||
| 602 | std::string area_name = room_name; | 605 | std::string area_name = room_name; |
| 603 | if (fold_areas.count(room_name)) { | 606 | std::string section_name = panel.name; |
| 604 | int fold_area_id = fold_areas[room_name]; | 607 | std::string location_name = room_name + " - " + panel.name; |
| 608 | |||
| 609 | if (!panel.location_name.empty()) { | ||
| 610 | location_name = panel.location_name; | ||
| 611 | |||
| 612 | size_t divider_pos = location_name.find(" - "); | ||
| 613 | if (divider_pos != std::string::npos) { | ||
| 614 | area_name = location_name.substr(0, divider_pos); | ||
| 615 | section_name = location_name.substr(divider_pos + 3); | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | if (fold_areas.count(area_name)) { | ||
| 620 | int fold_area_id = fold_areas[area_name]; | ||
| 605 | area_name = map_areas_[fold_area_id].name; | 621 | area_name = map_areas_[fold_area_id].name; |
| 606 | } | 622 | } |
| 607 | 623 | ||
| @@ -617,15 +633,15 @@ struct GameData { | |||
| 617 | MapArea &map_area = map_areas_[area_id]; | 633 | MapArea &map_area = map_areas_[area_id]; |
| 618 | // room field should be the original room ID | 634 | // room field should be the original room ID |
| 619 | map_area.locations.push_back( | 635 | map_area.locations.push_back( |
| 620 | {.name = panel.name, | 636 | {.name = section_name, |
| 621 | .ap_location_name = room_name + " - " + panel.name, | 637 | .ap_location_name = location_name, |
| 622 | .ap_location_id = panel.ap_location_id, | 638 | .ap_location_id = panel.ap_location_id, |
| 623 | .room = panel.room, | 639 | .room = panel.room, |
| 624 | .panels = {panel.id}, | 640 | .panels = {panel.id}, |
| 625 | .classification = classification, | 641 | .classification = classification, |
| 626 | .hunt = panel.hunt}); | 642 | .hunt = panel.hunt}); |
| 627 | locations_by_name[map_area.locations.back().ap_location_name] = { | 643 | locations_by_name[location_name] = {area_id, |
| 628 | area_id, map_area.locations.size() - 1}; | 644 | map_area.locations.size() - 1}; |
| 629 | } | 645 | } |
| 630 | 646 | ||
| 631 | for (int door_id : door_definition_order_) { | 647 | for (int door_id : door_definition_order_) { |
| @@ -679,11 +695,101 @@ struct GameData { | |||
| 679 | } | 695 | } |
| 680 | } | 696 | } |
| 681 | 697 | ||
| 698 | for (const Room &room : rooms_) { | ||
| 699 | std::string area_name = room.name; | ||
| 700 | if (fold_areas.count(room.name)) { | ||
| 701 | int fold_area_id = fold_areas[room.name]; | ||
| 702 | area_name = map_areas_[fold_area_id].name; | ||
| 703 | } | ||
| 704 | |||
| 705 | if (!room.paintings.empty()) { | ||
| 706 | int area_id = AddOrGetArea(area_name); | ||
| 707 | MapArea &map_area = map_areas_[area_id]; | ||
| 708 | |||
| 709 | for (int painting_id : room.paintings) { | ||
| 710 | const PaintingExit &painting_obj = paintings_.at(painting_id); | ||
| 711 | if (painting_obj.entrance) { | ||
| 712 | map_area.paintings.push_back(painting_id); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 682 | // Report errors. | 718 | // Report errors. |
| 683 | for (const std::string &area : malconfigured_areas_) { | 719 | for (const std::string &area : malconfigured_areas_) { |
| 684 | std::ostringstream errstr; | 720 | wxLogError("Area data not found for: %s", area); |
| 685 | errstr << "Area data not found for: " << area; | 721 | } |
| 686 | TrackerLog(errstr.str()); | 722 | |
| 723 | // Read in subway items. | ||
| 724 | YAML::Node subway_config = | ||
| 725 | YAML::LoadFile(GetAbsolutePath("assets/subway.yaml")); | ||
| 726 | for (const auto &subway_it : subway_config) { | ||
| 727 | SubwayItem subway_item; | ||
| 728 | subway_item.id = subway_items_.size(); | ||
| 729 | subway_item.x = subway_it["pos"][0].as<int>(); | ||
| 730 | subway_item.y = subway_it["pos"][1].as<int>(); | ||
| 731 | |||
| 732 | if (subway_it["door"]) { | ||
| 733 | subway_item.door = AddOrGetDoor(subway_it["room"].as<std::string>(), | ||
| 734 | subway_it["door"].as<std::string>()); | ||
| 735 | } | ||
| 736 | |||
| 737 | if (subway_it["paintings"]) { | ||
| 738 | for (const auto &painting_it : subway_it["paintings"]) { | ||
| 739 | std::string painting_id = painting_it.as<std::string>(); | ||
| 740 | |||
| 741 | subway_item.paintings.push_back(painting_id); | ||
| 742 | subway_item_by_painting_[painting_id] = subway_item.id; | ||
| 743 | } | ||
| 744 | } | ||
| 745 | |||
| 746 | if (subway_it["tags"]) { | ||
| 747 | for (const auto &tag_it : subway_it["tags"]) { | ||
| 748 | subway_item.tags.push_back(tag_it.as<std::string>()); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | |||
| 752 | if (subway_it["sunwarp"]) { | ||
| 753 | SubwaySunwarp sunwarp; | ||
| 754 | sunwarp.dots = subway_it["sunwarp"]["dots"].as<int>(); | ||
| 755 | |||
| 756 | std::string sunwarp_type = | ||
| 757 | subway_it["sunwarp"]["type"].as<std::string>(); | ||
| 758 | if (sunwarp_type == "final") { | ||
| 759 | sunwarp.type = SubwaySunwarpType::kFinal; | ||
| 760 | } else if (sunwarp_type == "exit") { | ||
| 761 | sunwarp.type = SubwaySunwarpType::kExit; | ||
| 762 | } else { | ||
| 763 | sunwarp.type = SubwaySunwarpType::kEnter; | ||
| 764 | } | ||
| 765 | |||
| 766 | subway_item.sunwarp = sunwarp; | ||
| 767 | |||
| 768 | subway_item_by_sunwarp_[sunwarp] = subway_item.id; | ||
| 769 | |||
| 770 | subway_item.door = | ||
| 771 | AddOrGetDoor("Sunwarps", std::to_string(sunwarp.dots) + " Sunwarp"); | ||
| 772 | } | ||
| 773 | |||
| 774 | if (subway_it["special"]) { | ||
| 775 | subway_item.special = subway_it["special"].as<std::string>(); | ||
| 776 | } | ||
| 777 | |||
| 778 | subway_items_.push_back(subway_item); | ||
| 779 | } | ||
| 780 | |||
| 781 | // Find singleton subway tags. | ||
| 782 | std::map<std::string, std::set<int>> subway_tags; | ||
| 783 | for (const SubwayItem &subway_item : subway_items_) { | ||
| 784 | for (const std::string &tag : subway_item.tags) { | ||
| 785 | subway_tags[tag].insert(subway_item.id); | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 789 | for (const auto &[tag, items] : subway_tags) { | ||
| 790 | if (items.size() == 1) { | ||
| 791 | wxLogWarning("Singleton subway item tag: %s", tag); | ||
| 792 | } | ||
| 687 | } | 793 | } |
| 688 | } | 794 | } |
| 689 | 795 | ||
| @@ -700,8 +806,10 @@ struct GameData { | |||
| 700 | std::string full_name = room + " - " + door; | 806 | std::string full_name = room + " - " + door; |
| 701 | 807 | ||
| 702 | if (!door_by_id_.count(full_name)) { | 808 | if (!door_by_id_.count(full_name)) { |
| 809 | int door_id = doors_.size(); | ||
| 703 | door_by_id_[full_name] = doors_.size(); | 810 | door_by_id_[full_name] = doors_.size(); |
| 704 | doors_.push_back({.room = AddOrGetRoom(room), .name = door}); | 811 | doors_.push_back( |
| 812 | {.id = door_id, .room = AddOrGetRoom(room), .name = door}); | ||
| 705 | } | 813 | } |
| 706 | 814 | ||
| 707 | return door_by_id_[full_name]; | 815 | return door_by_id_[full_name]; |
| @@ -745,6 +853,16 @@ struct GameData { | |||
| 745 | 853 | ||
| 746 | return area_by_id_[area]; | 854 | return area_by_id_[area]; |
| 747 | } | 855 | } |
| 856 | |||
| 857 | int AddOrGetPainting(std::string internal_id) { | ||
| 858 | if (!painting_by_id_.count(internal_id)) { | ||
| 859 | int painting_id = paintings_.size(); | ||
| 860 | painting_by_id_[internal_id] = painting_id; | ||
| 861 | paintings_.push_back({.id = painting_id, .internal_id = internal_id}); | ||
| 862 | } | ||
| 863 | |||
| 864 | return painting_by_id_[internal_id]; | ||
| 865 | } | ||
| 748 | }; | 866 | }; |
| 749 | 867 | ||
| 750 | GameData &GetState() { | 868 | GameData &GetState() { |
| @@ -754,6 +872,10 @@ GameData &GetState() { | |||
| 754 | 872 | ||
| 755 | } // namespace | 873 | } // namespace |
| 756 | 874 | ||
| 875 | bool SubwaySunwarp::operator<(const SubwaySunwarp &rhs) const { | ||
| 876 | return std::tie(dots, type) < std::tie(rhs.dots, rhs.type); | ||
| 877 | } | ||
| 878 | |||
| 757 | const std::vector<MapArea> &GD_GetMapAreas() { return GetState().map_areas_; } | 879 | const std::vector<MapArea> &GD_GetMapAreas() { return GetState().map_areas_; } |
| 758 | 880 | ||
| 759 | const MapArea &GD_GetMapArea(int id) { return GetState().map_areas_.at(id); } | 881 | const MapArea &GD_GetMapArea(int id) { return GetState().map_areas_.at(id); } |
| @@ -780,8 +902,12 @@ const Panel &GD_GetPanel(int panel_id) { | |||
| 780 | return GetState().panels_.at(panel_id); | 902 | return GetState().panels_.at(panel_id); |
| 781 | } | 903 | } |
| 782 | 904 | ||
| 783 | int GD_GetRoomForPainting(const std::string &painting_id) { | 905 | const PaintingExit &GD_GetPaintingExit(int painting_id) { |
| 784 | return GetState().room_by_painting_.at(painting_id); | 906 | return GetState().paintings_.at(painting_id); |
| 907 | } | ||
| 908 | |||
| 909 | int GD_GetPaintingByName(const std::string &name) { | ||
| 910 | return GetState().painting_by_id_.at(name); | ||
| 785 | } | 911 | } |
| 786 | 912 | ||
| 787 | const std::vector<int> &GD_GetAchievementPanels() { | 913 | const std::vector<int> &GD_GetAchievementPanels() { |
| @@ -799,3 +925,24 @@ const std::vector<int> &GD_GetSunwarpDoors() { | |||
| 799 | int GD_GetRoomForSunwarp(int index) { | 925 | int GD_GetRoomForSunwarp(int index) { |
| 800 | return GetState().room_by_sunwarp_.at(index); | 926 | return GetState().room_by_sunwarp_.at(index); |
| 801 | } | 927 | } |
| 928 | |||
| 929 | const std::vector<SubwayItem> &GD_GetSubwayItems() { | ||
| 930 | return GetState().subway_items_; | ||
| 931 | } | ||
| 932 | |||
| 933 | const SubwayItem &GD_GetSubwayItem(int id) { | ||
| 934 | return GetState().subway_items_.at(id); | ||
| 935 | } | ||
| 936 | |||
| 937 | int GD_GetSubwayItemForPainting(const std::string &painting_id) { | ||
| 938 | #ifndef NDEBUG | ||
| 939 | if (!GetState().subway_item_by_painting_.count(painting_id)) { | ||
| 940 | wxLogError("No subway item for painting %s", painting_id); | ||
| 941 | } | ||
| 942 | #endif | ||
| 943 | return GetState().subway_item_by_painting_.at(painting_id); | ||
| 944 | } | ||
| 945 | |||
| 946 | int GD_GetSubwayItemForSunwarp(const SubwaySunwarp &sunwarp) { | ||
| 947 | return GetState().subway_item_by_sunwarp_.at(sunwarp); | ||
| 948 | } | ||
