diff options
Diffstat (limited to 'tools/validator')
| -rw-r--r-- | tools/validator/human_processor.cpp | 56 | ||||
| -rw-r--r-- | tools/validator/main.cpp | 4 | ||||
| -rw-r--r-- | tools/validator/structs.h | 10 | ||||
| -rw-r--r-- | tools/validator/validator.cpp | 88 | ||||
| -rw-r--r-- | tools/validator/validator.h | 2 |
5 files changed, 131 insertions, 29 deletions
| diff --git a/tools/validator/human_processor.cpp b/tools/validator/human_processor.cpp index 2c978bf..d6fcfa6 100644 --- a/tools/validator/human_processor.cpp +++ b/tools/validator/human_processor.cpp | |||
| @@ -74,9 +74,35 @@ class HumanProcessor { | |||
| 74 | MapInfo& map_info = info_.maps[current_map_name]; | 74 | MapInfo& map_info = info_.maps[current_map_name]; |
| 75 | 75 | ||
| 76 | auto metadata = ReadMessageFromFile<HumanMap>(path.string()); | 76 | auto metadata = ReadMessageFromFile<HumanMap>(path.string()); |
| 77 | map_info.definitions.push_back(metadata); | ||
| 78 | |||
| 77 | for (const std::string& path : metadata.excluded_nodes()) { | 79 | for (const std::string& path : metadata.excluded_nodes()) { |
| 78 | map_info.game_nodes[path].uses++; | 80 | map_info.game_nodes[path].uses++; |
| 79 | } | 81 | } |
| 82 | |||
| 83 | for (const std::string& path : metadata.custom_nodes()) { | ||
| 84 | map_info.game_nodes[path].defined = true; | ||
| 85 | } | ||
| 86 | |||
| 87 | if (metadata.has_worldport_entrance()) { | ||
| 88 | auto port_identifier = GetCompletePortIdentifier( | ||
| 89 | metadata.worldport_entrance(), current_map_name, std::nullopt); | ||
| 90 | if (port_identifier) { | ||
| 91 | PortInfo& port_info = info_.ports[*port_identifier]; | ||
| 92 | port_info.map_worldport_entrances.push_back(current_map_name); | ||
| 93 | } else { | ||
| 94 | map_info.malformed_worldport_entrance = metadata.worldport_entrance(); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | if (metadata.has_rte_room()) { | ||
| 99 | RoomIdentifier room_identifier; | ||
| 100 | room_identifier.set_map(current_map_name); | ||
| 101 | room_identifier.set_name(metadata.rte_room()); | ||
| 102 | |||
| 103 | RoomInfo& room_info = info_.rooms[room_identifier]; | ||
| 104 | room_info.map_rtes_referenced_by.push_back(current_map_name); | ||
| 105 | } | ||
| 80 | } | 106 | } |
| 81 | 107 | ||
| 82 | void ProcessRooms(std::filesystem::path path, | 108 | void ProcessRooms(std::filesystem::path path, |
| @@ -358,11 +384,6 @@ class HumanProcessor { | |||
| 358 | DoorInfo& other_door_info = info_.doors[complete_door_identifier]; | 384 | DoorInfo& other_door_info = info_.doors[complete_door_identifier]; |
| 359 | other_door_info.doors_referenced_by.push_back(door_identifier); | 385 | other_door_info.doors_referenced_by.push_back(door_identifier); |
| 360 | } | 386 | } |
| 361 | |||
| 362 | for (const std::string& ei : h_door.endings()) { | ||
| 363 | EndingInfo& ending_info = info_.endings[ei]; | ||
| 364 | ending_info.doors_referenced_by.push_back(door_identifier); | ||
| 365 | } | ||
| 366 | } | 387 | } |
| 367 | 388 | ||
| 368 | void ProcessConnectionsFile(std::filesystem::path path, | 389 | void ProcessConnectionsFile(std::filesystem::path path, |
| @@ -560,12 +581,14 @@ class HumanProcessor { | |||
| 560 | auto ids = ReadIdsFromYaml(path.string()); | 581 | auto ids = ReadIdsFromYaml(path.string()); |
| 561 | 582 | ||
| 562 | DoorIdentifier di; | 583 | DoorIdentifier di; |
| 563 | PanelIdentifier pi; | 584 | PanelIdentifier pai; |
| 585 | PortIdentifier poi; | ||
| 564 | KeyholderIdentifier ki; | 586 | KeyholderIdentifier ki; |
| 565 | 587 | ||
| 566 | for (const auto& [map_name, map] : ids.maps()) { | 588 | for (const auto& [map_name, map] : ids.maps()) { |
| 567 | di.set_map(map_name); | 589 | di.set_map(map_name); |
| 568 | pi.set_map(map_name); | 590 | pai.set_map(map_name); |
| 591 | poi.set_map(map_name); | ||
| 569 | ki.set_map(map_name); | 592 | ki.set_map(map_name); |
| 570 | 593 | ||
| 571 | for (const auto& [door_name, ap_id] : map.doors()) { | 594 | for (const auto& [door_name, ap_id] : map.doors()) { |
| @@ -576,13 +599,14 @@ class HumanProcessor { | |||
| 576 | } | 599 | } |
| 577 | 600 | ||
| 578 | for (const auto& [room_name, room] : map.rooms()) { | 601 | for (const auto& [room_name, room] : map.rooms()) { |
| 579 | pi.set_room(room_name); | 602 | pai.set_room(room_name); |
| 603 | poi.set_room(room_name); | ||
| 580 | ki.set_room(room_name); | 604 | ki.set_room(room_name); |
| 581 | 605 | ||
| 582 | for (const auto& [panel_name, ap_id] : room.panels()) { | 606 | for (const auto& [panel_name, ap_id] : room.panels()) { |
| 583 | pi.set_name(panel_name); | 607 | pai.set_name(panel_name); |
| 584 | 608 | ||
| 585 | PanelInfo& panel_info = info_.panels[pi]; | 609 | PanelInfo& panel_info = info_.panels[pai]; |
| 586 | panel_info.has_id = true; | 610 | panel_info.has_id = true; |
| 587 | } | 611 | } |
| 588 | 612 | ||
| @@ -596,6 +620,18 @@ class HumanProcessor { | |||
| 596 | KeyholderInfo& keyholder_info = info_.keyholders[ki]; | 620 | KeyholderInfo& keyholder_info = info_.keyholders[ki]; |
| 597 | keyholder_info.has_id = true; | 621 | keyholder_info.has_id = true; |
| 598 | } | 622 | } |
| 623 | |||
| 624 | for (const auto& [port_name, ap_id] : room.ports()) { | ||
| 625 | poi.set_name(port_name); | ||
| 626 | |||
| 627 | PortInfo& port_info = info_.ports[poi]; | ||
| 628 | port_info.has_id = true; | ||
| 629 | } | ||
| 630 | } | ||
| 631 | |||
| 632 | if (map.has_rte()) { | ||
| 633 | MapInfo& map_info = info_.maps[map_name]; | ||
| 634 | map_info.has_rte_id = true; | ||
| 599 | } | 635 | } |
| 600 | } | 636 | } |
| 601 | 637 | ||
| diff --git a/tools/validator/main.cpp b/tools/validator/main.cpp index 1a72e9a..6139e95 100644 --- a/tools/validator/main.cpp +++ b/tools/validator/main.cpp | |||
| @@ -21,7 +21,9 @@ void Run(const std::string& mapdir, const std::string& repodir) { | |||
| 21 | int main(int argc, char** argv) { | 21 | int main(int argc, char** argv) { |
| 22 | if (argc != 3) { | 22 | if (argc != 3) { |
| 23 | std::cout << "Incorrect argument count." << std::endl; | 23 | std::cout << "Incorrect argument count." << std::endl; |
| 24 | std::cout << "Usage: validator [path to map directory] [path to Lingo 2 repository]" << std::endl; | 24 | std::cout << "Usage: validator [path to map directory] [path to Lingo 2 " |
| 25 | "repository]" | ||
| 26 | << std::endl; | ||
| 25 | return 1; | 27 | return 1; |
| 26 | } | 28 | } |
| 27 | 29 | ||
| diff --git a/tools/validator/structs.h b/tools/validator/structs.h index d1d45f2..81a0e8f 100644 --- a/tools/validator/structs.h +++ b/tools/validator/structs.h | |||
| @@ -27,6 +27,11 @@ struct GameNodeInfo { | |||
| 27 | 27 | ||
| 28 | struct MapInfo { | 28 | struct MapInfo { |
| 29 | std::map<std::string, GameNodeInfo> game_nodes; | 29 | std::map<std::string, GameNodeInfo> game_nodes; |
| 30 | |||
| 31 | std::vector<HumanMap> definitions; | ||
| 32 | bool has_rte_id = false; | ||
| 33 | |||
| 34 | std::optional<PortIdentifier> malformed_worldport_entrance; | ||
| 30 | }; | 35 | }; |
| 31 | 36 | ||
| 32 | struct RoomInfo { | 37 | struct RoomInfo { |
| @@ -35,6 +40,7 @@ struct RoomInfo { | |||
| 35 | std::vector<DoorIdentifier> doors_referenced_by; | 40 | std::vector<DoorIdentifier> doors_referenced_by; |
| 36 | std::vector<PanelIdentifier> panels_referenced_by; | 41 | std::vector<PanelIdentifier> panels_referenced_by; |
| 37 | std::vector<HumanConnection> connections_referenced_by; | 42 | std::vector<HumanConnection> connections_referenced_by; |
| 43 | std::vector<std::string> map_rtes_referenced_by; | ||
| 38 | }; | 44 | }; |
| 39 | 45 | ||
| 40 | struct DoorInfo { | 46 | struct DoorInfo { |
| @@ -54,9 +60,11 @@ struct DoorInfo { | |||
| 54 | 60 | ||
| 55 | struct PortInfo { | 61 | struct PortInfo { |
| 56 | std::vector<HumanPort> definitions; | 62 | std::vector<HumanPort> definitions; |
| 63 | bool has_id = false; | ||
| 57 | 64 | ||
| 58 | std::vector<HumanConnection> connections_referenced_by; | 65 | std::vector<HumanConnection> connections_referenced_by; |
| 59 | std::vector<HumanConnection> target_connections_referenced_by; | 66 | std::vector<HumanConnection> target_connections_referenced_by; |
| 67 | std::vector<std::string> map_worldport_entrances; | ||
| 60 | }; | 68 | }; |
| 61 | 69 | ||
| 62 | struct PaintingInfo { | 70 | struct PaintingInfo { |
| @@ -104,8 +112,6 @@ struct LetterInfo { | |||
| 104 | struct EndingInfo { | 112 | struct EndingInfo { |
| 105 | std::vector<RoomIdentifier> defined_in; | 113 | std::vector<RoomIdentifier> defined_in; |
| 106 | bool has_id = false; | 114 | bool has_id = false; |
| 107 | |||
| 108 | std::vector<DoorIdentifier> doors_referenced_by; | ||
| 109 | }; | 115 | }; |
| 110 | 116 | ||
| 111 | struct PanelNameInfo { | 117 | struct PanelNameInfo { |
| diff --git a/tools/validator/validator.cpp b/tools/validator/validator.cpp index dd41f5c..e9fbb74 100644 --- a/tools/validator/validator.cpp +++ b/tools/validator/validator.cpp | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #include "validator.h" | 1 | #include "validator.h" |
| 2 | 2 | ||
| 3 | #include <algorithm> | ||
| 3 | #include <iostream> | 4 | #include <iostream> |
| 4 | 5 | ||
| 5 | #include "proto/human.pb.h" | 6 | #include "proto/human.pb.h" |
| @@ -69,6 +70,27 @@ class Validator { | |||
| 69 | << " is not defined in the game file." << std::endl; | 70 | << " is not defined in the game file." << std::endl; |
| 70 | } | 71 | } |
| 71 | } | 72 | } |
| 73 | |||
| 74 | if (map_info.malformed_worldport_entrance) { | ||
| 75 | std::cout << "The worldport entrance for map " << map_name | ||
| 76 | << " is malformed." << std::endl; | ||
| 77 | } | ||
| 78 | |||
| 79 | if (map_info.has_rte_id) { | ||
| 80 | if (!std::any_of( | ||
| 81 | map_info.definitions.begin(), map_info.definitions.end(), | ||
| 82 | [](const HumanMap& h_map) { return h_map.has_rte_room(); })) { | ||
| 83 | std::cout << "Map " << map_name << " has an RTE ID but no RTE room." | ||
| 84 | << std::endl; | ||
| 85 | } | ||
| 86 | } else { | ||
| 87 | if (std::any_of( | ||
| 88 | map_info.definitions.begin(), map_info.definitions.end(), | ||
| 89 | [](const HumanMap& h_map) { return h_map.has_rte_room(); })) { | ||
| 90 | std::cout << "Map " << map_name << " has an RTE room but no RTE ID." | ||
| 91 | << std::endl; | ||
| 92 | } | ||
| 93 | } | ||
| 72 | } | 94 | } |
| 73 | 95 | ||
| 74 | void ValidateRoom(const RoomIdentifier& room_identifier, | 96 | void ValidateRoom(const RoomIdentifier& room_identifier, |
| @@ -94,6 +116,10 @@ class Validator { | |||
| 94 | std::cout << " CONNECTION " << connection.ShortDebugString() | 116 | std::cout << " CONNECTION " << connection.ShortDebugString() |
| 95 | << std::endl; | 117 | << std::endl; |
| 96 | } | 118 | } |
| 119 | |||
| 120 | for (const std::string& map_name : room_info.map_rtes_referenced_by) { | ||
| 121 | std::cout << " MAP RTE " << map_name << std::endl; | ||
| 122 | } | ||
| 97 | } else if (room_info.definitions.size() > 1) { | 123 | } else if (room_info.definitions.size() > 1) { |
| 98 | std::cout << "Room " << room_identifier.ShortDebugString() | 124 | std::cout << "Room " << room_identifier.ShortDebugString() |
| 99 | << " was defined multiple times." << std::endl; | 125 | << " was defined multiple times." << std::endl; |
| @@ -106,7 +132,7 @@ class Validator { | |||
| 106 | return false; | 132 | return false; |
| 107 | } | 133 | } |
| 108 | 134 | ||
| 109 | if (h_door.keyholders_size() > 0 || h_door.endings_size() > 0 || | 135 | if (h_door.keyholders_size() > 0 || h_door.white_ending() || |
| 110 | h_door.complete_at() > 0) { | 136 | h_door.complete_at() > 0) { |
| 111 | return true; | 137 | return true; |
| 112 | } | 138 | } |
| @@ -220,16 +246,23 @@ class Validator { | |||
| 220 | << " needs an explicit location name." << std::endl; | 246 | << " needs an explicit location name." << std::endl; |
| 221 | } | 247 | } |
| 222 | 248 | ||
| 223 | if (h_door.double_letters() && | 249 | if (h_door.type() == DoorType::STANDARD || |
| 224 | (h_door.type() == DoorType::STANDARD || | 250 | h_door.type() == DoorType::LOCATION_ONLY || |
| 225 | h_door.type() == DoorType::LOCATION_ONLY || | 251 | h_door.type() == DoorType::GRAVESTONE || h_door.legacy_location()) { |
| 226 | h_door.type() == DoorType::GRAVESTONE)) { | 252 | if (h_door.double_letters()) { |
| 227 | std::cout << "Door " << door_identifier.ShortDebugString() | 253 | std::cout << "Door " << door_identifier.ShortDebugString() |
| 228 | << " is a location that depends on double_letters." | 254 | << " is a location that depends on double_letters." |
| 229 | << std::endl; | 255 | << std::endl; |
| 256 | } | ||
| 257 | |||
| 258 | if (!h_door.has_location_room()) { | ||
| 259 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
| 260 | << " is missing a location_room." << std::endl; | ||
| 261 | } | ||
| 230 | } | 262 | } |
| 231 | 263 | ||
| 232 | bool needs_id = (h_door.type() != DoorType::EVENT); | 264 | bool needs_id = (h_door.type() != DoorType::EVENT || h_door.latch() || |
| 265 | h_door.legacy_location()); | ||
| 233 | if (door_info.has_id != needs_id) { | 266 | if (door_info.has_id != needs_id) { |
| 234 | if (needs_id) { | 267 | if (needs_id) { |
| 235 | std::cout << "Door " << door_identifier.ShortDebugString() | 268 | std::cout << "Door " << door_identifier.ShortDebugString() |
| @@ -253,6 +286,14 @@ class Validator { | |||
| 253 | std::cout << " CONNECTION " << connection.ShortDebugString() | 286 | std::cout << " CONNECTION " << connection.ShortDebugString() |
| 254 | << std::endl; | 287 | << std::endl; |
| 255 | } | 288 | } |
| 289 | |||
| 290 | for (const std::string& map_name : port_info.map_worldport_entrances) { | ||
| 291 | std::cout << " MAP (worldport_entrance) " << map_name << std::endl; | ||
| 292 | } | ||
| 293 | |||
| 294 | if (port_info.has_id) { | ||
| 295 | std::cout << " An AP ID is present." << std::endl; | ||
| 296 | } | ||
| 256 | } else if (port_info.definitions.size() > 1) { | 297 | } else if (port_info.definitions.size() > 1) { |
| 257 | std::cout << "Port " << port_identifier.ShortDebugString() | 298 | std::cout << "Port " << port_identifier.ShortDebugString() |
| 258 | << " was defined multiple times." << std::endl; | 299 | << " was defined multiple times." << std::endl; |
| @@ -273,6 +314,29 @@ class Validator { | |||
| 273 | } | 314 | } |
| 274 | } | 315 | } |
| 275 | } | 316 | } |
| 317 | |||
| 318 | for (const HumanPort& port : port_info.definitions) { | ||
| 319 | if (!port.no_shuffle()) { | ||
| 320 | if (!port.has_destination()) { | ||
| 321 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
| 322 | << " is shuffleable and missing a destination." | ||
| 323 | << std::endl; | ||
| 324 | } | ||
| 325 | if (!port.has_rotation()) { | ||
| 326 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
| 327 | << " is shuffleable and missing a rotation." << std::endl; | ||
| 328 | } | ||
| 329 | if (!port_info.has_id) { | ||
| 330 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
| 331 | << " is missing an AP ID." << std::endl; | ||
| 332 | } | ||
| 333 | } else { | ||
| 334 | if (port_info.has_id) { | ||
| 335 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
| 336 | << " should not have an AP ID." << std::endl; | ||
| 337 | } | ||
| 338 | } | ||
| 339 | } | ||
| 276 | } | 340 | } |
| 277 | 341 | ||
| 278 | void ValidatePainting(const PaintingIdentifier& painting_identifier, | 342 | void ValidatePainting(const PaintingIdentifier& painting_identifier, |
| @@ -459,12 +523,6 @@ class Validator { | |||
| 459 | std::cout << "Ending " << ending_name | 523 | std::cout << "Ending " << ending_name |
| 460 | << " has no definition, but was referenced:" << std::endl; | 524 | << " has no definition, but was referenced:" << std::endl; |
| 461 | 525 | ||
| 462 | for (const DoorIdentifier& door_identifier : | ||
| 463 | ending_info.doors_referenced_by) { | ||
| 464 | std::cout << " DOOR " << door_identifier.ShortDebugString() | ||
| 465 | << std::endl; | ||
| 466 | } | ||
| 467 | |||
| 468 | if (ending_info.has_id) { | 526 | if (ending_info.has_id) { |
| 469 | std::cout << " An AP ID is present." << std::endl; | 527 | std::cout << " An AP ID is present." << std::endl; |
| 470 | } | 528 | } |
| diff --git a/tools/validator/validator.h b/tools/validator/validator.h index b710429..33bc7c9 100644 --- a/tools/validator/validator.h +++ b/tools/validator/validator.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #ifndef TOOLS_VALIDATOR_VALIDATOR_H_ | 1 | #ifndef TOOLS_VALIDATOR_VALIDATOR_H |
| 2 | #define TOOLS_VALIDATOR_VALIDATOR_H | 2 | #define TOOLS_VALIDATOR_VALIDATOR_H |
| 3 | 3 | ||
| 4 | namespace com::fourisland::lingo2_archipelago { | 4 | namespace com::fourisland::lingo2_archipelago { |
