about summary refs log tree commit diff stats
Commit message (Collapse)AuthorAgeFilesLines
...
* [Client] Prevent text client on connection screenStar Rauchenberger2025-09-083-1/+13
|
* [Client] Handle lavender cubesStar Rauchenberger2025-09-081-1/+4
|
* Added lavender cubes logicStar Rauchenberger2025-09-0812-16/+53
|
* [Client] Handle cyan door behaviorStar Rauchenberger2025-09-082-19/+52
| | | | Player still needs to leave and re-enter the map for "any double letter" value.
* [Data] the_great/BYE is behind a "cyan door"Star Rauchenberger2025-09-083-0/+11
|
* Add cyan door behavior optionStar Rauchenberger2025-09-0812-14/+122
|
* [Client] Handle grouped doors / shuffled CC doorsStar Rauchenberger2025-09-071-0/+17
|
* [Apworld] Add shuffle_control_center_colors to slot dataStar Rauchenberger2025-09-071-0/+1
|
* Added door groupsStar Rauchenberger2025-09-0720-16/+326
|
* [Data] Renamed some locationsStar Rauchenberger2025-09-075-0/+7
|
* [Client] Location scouting for lettersStar Rauchenberger2025-09-065-8/+89
|
* [Client] Handle letter shuffleStar Rauchenberger2025-09-069-15/+345
| | | | Cyan doors are not handled properly yet.
* [Apworld] Added letter shuffleStar Rauchenberger2025-09-065-27/+114
|
* [Client] Client pause mode?Star Rauchenberger2025-09-051-0/+2
|
* [Data] Replaced Symbolic Entrance with single doorStar Rauchenberger2025-09-053-45/+19
|
* [Client] Maybe for real fixed the crash on connectStar Rauchenberger2025-09-051-2/+1
|
* [Client] Fixed external names in messages popupStar Rauchenberger2025-09-041-8/+8
|
* [Client] Handle roof access optionStar Rauchenberger2025-09-042-1/+3
|
* [Data] Strip unnecessary AP IDsStar Rauchenberger2025-09-045-35/+208
| | | | This was causing issues in the client, specifically for The Ancient.
* Renamed filler item to "A Job Well Done"Star Rauchenberger2025-09-033-4/+8
|
* Added option for Daedalus roof access logicStar Rauchenberger2025-09-039-0/+343
|
* [Client] Handle keyholder sanityStar Rauchenberger2025-09-022-2/+28
|
* Added keyholder sanityStar Rauchenberger2025-09-0233-8/+183
|
* [Client] Handle progressive doorsStar Rauchenberger2025-09-017-63/+99
|
* [Client] Fix intermittent crash on connectStar Rauchenberger2025-09-011-1/+1
|
* [Data] Question Room What proxies were mislabeledStar Rauchenberger2025-09-011-5/+5
|
* Added progressive doorsStar Rauchenberger2025-09-0115-38/+219
|
* [Data] Fixed Rainbow Rooms logicStar Rauchenberger2025-09-012-18/+20
|
* [Client] Display message when goalingStar Rauchenberger2025-09-011-0/+2
|
* [Data] Some more double letters fixesStar Rauchenberger2025-09-014-1/+9
|
* [Client] Handle triggering goalStar Rauchenberger2025-09-015-3/+51
|
* [Client] Batch sending locations on map loadStar Rauchenberger2025-08-313-1/+27
|
* [Client] Restrict Daedalus roof accessStar Rauchenberger2025-08-311-0/+50
|
* [Client] Keyholders in locationsStar Rauchenberger2025-08-311-0/+19
|
* [Data] Couple of renamesStar Rauchenberger2025-08-314-2/+4
|
* [Apworld] Added options to slot dataStar Rauchenberger2025-08-311-0/+11
|
* [Apworld] Better handling of White EndingStar Rauchenberger2025-08-311-2/+14
| | | | | It now has the correct logic, and also no location will be created for it.
* Handled cyan doorsStar Rauchenberger2025-08-3113-17/+37
|
* [Data] Small tweaksStar Rauchenberger2025-08-318-22/+34
|
* [Client] Handle locations needing specific answersStar Rauchenberger2025-08-301-2/+9
|
* [Client] Potentially fixed crash when loading corrupted localdataStar Rauchenberger2025-08-302-6/+4
|
* [Data] Small tweaksStar Rauchenberger2025-08-307-2/+16
|
* [Data] Bad logic in the_owl due to missing warpStar Rauchenberger2025-08-305-22/+23
|
* Changed how door location names are formattedStar Rauchenberger2025-08-30491-692/+798
| | | | | | | | | | | | | | | | | | STANDARD type doors with at most four panels in the same map area and no other trigger objects will have their location names generated from the names of the panels used to open the door, similar to Lingo 1. Other door types will use the door's name. In either case, the name can be overridden using the new location_name field. Rooms can also set a panel_display_name field, which will be used in location names for doors, and is used to group panels into areas. Panels themselves can set display names, which differentiates their locations from other panels in the same area. Many maps were updated for this, but note that the_symbolic and the_unyielding have validator failures because of duplicate panel names. This won't matter until panelsanity is implemented.
* [Apworld] Require CC access + letters for CC color doorsStar Rauchenberger2025-08-301-0/+4
|
* [Data] Wondrous gallery painting goes to huge roomStar Rauchenberger2025-08-301-1/+1
|
* [Data] Made proxies with the same answer as the panel explicitStar Rauchenberger2025-08-3022-37/+42
|
* [Data] Added logic for Tenacious Color PaintingStar Rauchenberger2025-08-302-1/+9
|
* [Data] S1 Door is not a location anymoreStar Rauchenberger2025-08-291-3/+1
|
* [Client] Added textclientStar Rauchenberger2025-08-294-0/+145
|
ss="w"> buffer; buffer << file.rdbuf(); T message; google::protobuf::TextFormat::ParseFromString(buffer.str(), &message); return message; } class HumanProcessor { public: HumanProcessor(const std::string& mapdir, CollectedInfo& info) : mapdir_(mapdir), info_(info) {} void Run() { std::filesystem::path datadir_path = mapdir_; ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt); ProcessMaps(datadir_path); ProcessProgressivesFile(datadir_path / "progressives.txtpb"); ProcessIdsFile(datadir_path / "ids.yaml"); } private: void ProcessMaps(std::filesystem::path path) { std::filesystem::path maps_dir = path / "maps"; for (auto const& dir_entry : std::filesystem::directory_iterator(maps_dir)) { ProcessMap(dir_entry.path()); } } void ProcessMap(std::filesystem::path path) { std::string map_name = path.filename().string(); ProcessMetadataFile(path / "metadata.txtpb", map_name); ProcessConnectionsFile(path / "connections.txtpb", map_name); ProcessDoorsFile(path / "doors.txtpb", map_name); ProcessRooms(path / "rooms", map_name); } void ProcessMetadataFile(std::filesystem::path path, const std::string& current_map_name) { if (!std::filesystem::exists(path)) { return; } MapInfo& map_info = info_.maps[current_map_name]; auto metadata = ReadMessageFromFile<HumanMap>(path.string()); for (const std::string& path : metadata.excluded_nodes()) { map_info.game_nodes[path].uses++; } } void ProcessRooms(std::filesystem::path path, const std::string& current_map_name) { for (auto const& dir_entry : std::filesystem::directory_iterator(path)) { auto room = ReadMessageFromFile<HumanRoom>(dir_entry.path().string()); ProcessRoom(room, current_map_name); } } void ProcessRoom(const HumanRoom& h_room, const std::string& current_map_name) { RoomIdentifier room_identifier; room_identifier.set_map(current_map_name); room_identifier.set_name(h_room.name()); RoomInfo& room_info = info_.rooms[room_identifier]; room_info.definitions.push_back(h_room); for (const HumanPanel& h_panel : h_room.panels()) { ProcessPanel(h_panel, current_map_name, h_room); } for (const HumanPainting& h_painting : h_room.paintings()) { ProcessPainting(h_painting, current_map_name, h_room.name()); } for (const HumanPort& h_port : h_room.ports()) { ProcessPort(h_port, current_map_name, h_room.name()); } for (const HumanLetter& h_letter : h_room.letters()) { ProcessLetter(h_letter, current_map_name, h_room.name()); } for (const HumanMastery& h_mastery : h_room.masteries()) { ProcessMastery(h_mastery, current_map_name, h_room.name()); } for (const HumanKeyholder& h_keyholder : h_room.keyholders()) { ProcessKeyholder(h_keyholder, current_map_name, h_room.name()); } for (const HumanEnding& h_ending : h_room.endings()) { ProcessEnding(h_ending, current_map_name, h_room.name()); } } void ProcessPanel(const HumanPanel& h_panel, const std::string& current_map_name, const HumanRoom& h_room) { PanelIdentifier panel_identifier; panel_identifier.set_map(current_map_name); panel_identifier.set_room(h_room.name()); panel_identifier.set_name(h_panel.name()); PanelInfo& panel_info = info_.panels[panel_identifier]; panel_info.definitions.push_back(h_panel); MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_panel.path()].uses++; for (const Proxy& h_proxy : h_panel.proxies()) { ProxyInfo& proxy_info = panel_info.proxies[h_proxy.answer()]; proxy_info.definitions.push_back(h_proxy); map_info.game_nodes[h_proxy.path()].uses++; } if (h_panel.has_required_door()) { DoorIdentifier required_door_identifier = *GetCompleteDoorIdentifier(h_panel.required_door(), current_map_name); DoorInfo& required_door_info = info_.doors[required_door_identifier]; required_door_info.panels_referenced_by.push_back(panel_identifier); } if (h_panel.has_required_room()) { RoomIdentifier required_room_identifier = *GetCompleteRoomIdentifier(h_panel.required_room(), current_map_name); RoomInfo& required_room_info = info_.rooms[required_room_identifier]; required_room_info.panels_referenced_by.push_back(panel_identifier); } std::string map_area_name = current_map_name; if (h_room.has_panel_display_name()) { map_area_name = fmt::format("{} ({})", current_map_name, h_room.panel_display_name()); } panel_info.map_area_name = map_area_name; std::string panelsanity_name; if (h_panel.has_display_name()) { panelsanity_name = fmt::format("{} - {}", map_area_name, h_panel.display_name()); } else { panelsanity_name = fmt::format("{} - {}", map_area_name, h_panel.name()); } info_.panel_names[panelsanity_name].panels_used_by.push_back( panel_identifier); } void ProcessPainting(const HumanPainting& h_painting, const std::string& current_map_name, const std::string& current_room_name) { PaintingIdentifier painting_identifier; painting_identifier.set_map(current_map_name); painting_identifier.set_room(current_room_name); painting_identifier.set_name(h_painting.name()); PaintingInfo& painting_info = info_.paintings[painting_identifier]; painting_info.definitions.push_back(h_painting); MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_painting.path()].uses++; if (h_painting.has_required_door()) { DoorIdentifier required_door_identifier = *GetCompleteDoorIdentifier( h_painting.required_door(), current_map_name); DoorInfo& required_door_info = info_.doors[required_door_identifier]; required_door_info.paintings_referenced_by.push_back(painting_identifier); } } void ProcessPort(const HumanPort& h_port, const std::string& current_map_name, const std::string& current_room_name) { PortIdentifier port_identifier; port_identifier.set_map(current_map_name); port_identifier.set_room(current_room_name); port_identifier.set_name(h_port.name()); PortInfo& port_info = info_.ports[port_identifier]; port_info.definitions.push_back(h_port); MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_port.path()].uses++; if (h_port.has_required_door()) { DoorIdentifier required_door_identifier = *GetCompleteDoorIdentifier(h_port.required_door(), current_map_name); DoorInfo& required_door_info = info_.doors[required_door_identifier]; required_door_info.ports_referenced_by.push_back(port_identifier); } } void ProcessLetter(const HumanLetter& h_letter, const std::string& current_map_name, const std::string& current_room_name) { LetterIdentifier letter_identifier = std::make_tuple(h_letter.key()[0], h_letter.level2()); LetterInfo& letter_info = info_.letters[letter_identifier]; RoomIdentifier room_identifier; room_identifier.set_map(current_map_name); room_identifier.set_name(current_room_name); letter_info.defined_in.push_back(room_identifier); MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_letter.path()].uses++; } void ProcessMastery(const HumanMastery& h_mastery, const std::string& current_map_name, const std::string& current_room_name) { MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_mastery.path()].uses++; } void ProcessKeyholder(const HumanKeyholder& h_keyholder, const std::string& current_map_name, const std::string& current_room_name) { KeyholderIdentifier keyholder_identifier; keyholder_identifier.set_map(current_map_name); keyholder_identifier.set_room(current_room_name); keyholder_identifier.set_name(h_keyholder.name()); KeyholderInfo& keyholder_info = info_.keyholders[keyholder_identifier]; keyholder_info.definitions.push_back(h_keyholder); MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_keyholder.path()].uses++; } void ProcessEnding(const HumanEnding& h_ending, const std::string& current_map_name, const std::string& current_room_name) { EndingInfo& ending_info = info_.endings[h_ending.name()]; RoomIdentifier room_identifier; room_identifier.set_map(current_map_name); room_identifier.set_name(current_room_name); ending_info.defined_in.push_back(room_identifier); MapInfo& map_info = info_.maps[current_map_name]; map_info.game_nodes[h_ending.path()].uses++; } void ProcessDoorsFile(std::filesystem::path path, const std::string& current_map_name) { if (!std::filesystem::exists(path)) { return; } auto doors = ReadMessageFromFile<HumanDoors>(path.string()); for (const HumanDoor& door : doors.doors()) { ProcessDoor(door, current_map_name); } } void ProcessDoor(const HumanDoor& h_door, const std::string& current_map_name) { DoorIdentifier door_identifier; door_identifier.set_map(current_map_name); door_identifier.set_name(h_door.name()); DoorInfo& door_info = info_.doors[door_identifier]; door_info.definitions.push_back(h_door); if (h_door.has_location_room()) { RoomIdentifier location_room_identifier; location_room_identifier.set_map(current_map_name); location_room_identifier.set_name(h_door.location_room()); info_.rooms[location_room_identifier].doors_referenced_by.push_back( door_identifier); } for (const PaintingIdentifier& pi : h_door.move_paintings()) { auto complete_painting_identifier = GetCompletePaintingIdentifier(pi, current_map_name, std::nullopt); if (complete_painting_identifier) { PaintingInfo& move_painting_info = info_.paintings[*complete_painting_identifier]; move_painting_info.doors_referenced_by.push_back(door_identifier); } else { door_info.malformed_identifiers.paintings.push_back(pi); } } for (const PanelIdentifier& pi : h_door.panels()) { auto complete_panel_identifier = GetCompletePanelIdentifierWithoutAnswer( pi, current_map_name, std::nullopt); if (complete_panel_identifier) { PanelInfo& panel_info = info_.panels[*complete_panel_identifier]; panel_info.doors_referenced_by.push_back(door_identifier); if (pi.has_answer()) { panel_info.proxies[pi.answer()].doors_referenced_by.push_back( door_identifier); } } else { door_info.malformed_identifiers.panels.push_back(pi); } } for (const KeyholderIdentifier& ki : h_door.keyholders()) { auto complete_keyholder_identifier = GetCompleteKeyholderIdentifierWithoutKey(ki, current_map_name, std::nullopt); if (complete_keyholder_identifier) { KeyholderInfo& keyholder_info = info_.keyholders[*complete_keyholder_identifier]; keyholder_info.doors_referenced_by.push_back(door_identifier); } else { door_info.malformed_identifiers.keyholders.push_back(ki); } } for (const RoomIdentifier& ri : h_door.rooms()) { RoomIdentifier complete_room_identifier = *GetCompleteRoomIdentifier(ri, current_map_name); RoomInfo& room_info = info_.rooms[complete_room_identifier]; room_info.doors_referenced_by.push_back(door_identifier); } for (const DoorIdentifier& di : h_door.doors()) { DoorIdentifier complete_door_identifier = *GetCompleteDoorIdentifier(di, current_map_name); DoorInfo& other_door_info = info_.doors[complete_door_identifier]; other_door_info.doors_referenced_by.push_back(door_identifier); } for (const std::string& ei : h_door.endings()) { EndingInfo& ending_info = info_.endings[ei]; ending_info.doors_referenced_by.push_back(door_identifier); } } void ProcessConnectionsFile(std::filesystem::path path, std::optional<std::string> current_map_name) { if (!std::filesystem::exists(path)) { return; } auto connections = ReadMessageFromFile<HumanConnections>(path.string()); for (const HumanConnection& connection : connections.connections()) { ProcessConnection(connection, current_map_name); } } void ProcessConnection(const HumanConnection& human_connection, const std::optional<std::string>& current_map_name) { if (human_connection.has_from_room()) { if (current_map_name) { RoomIdentifier room_identifier; room_identifier.set_map(*current_map_name); room_identifier.set_name(human_connection.from_room()); RoomInfo& room_info = info_.rooms[room_identifier]; room_info.connections_referenced_by.push_back(human_connection); } else { // Not sure where else to store this right now. std::cout << "A global connection used from_room." << std::endl; } } else if (human_connection.has_from()) { ProcessSingleConnection(human_connection, human_connection.from(), current_map_name); } if (human_connection.has_to_room()) { if (current_map_name) { RoomIdentifier room_identifier; room_identifier.set_map(*current_map_name); room_identifier.set_name(human_connection.to_room()); RoomInfo& room_info = info_.rooms[room_identifier]; room_info.connections_referenced_by.push_back(human_connection); } else { // Not sure where else to store this right now. std::cout << "A global connection used to_room." << std::endl; } } else if (human_connection.has_to()) { ProcessSingleConnection(human_connection, human_connection.to(), current_map_name); } if (human_connection.has_door()) { auto door_identifier = GetCompleteDoorIdentifier(human_connection.door(), current_map_name); if (door_identifier) { DoorInfo& door_info = info_.doors[*door_identifier]; door_info.connections_referenced_by.push_back(human_connection); } else { // Not sure where else to store this right now. std::cout << "A connection used the following malformed door identifier: " << human_connection.door().ShortDebugString() << std::endl; } } } void ProcessSingleConnection( const HumanConnection& human_connection, const HumanConnection::Endpoint& endpoint, const std::optional<std::string>& current_map_name) { if (endpoint.has_room()) { auto room_identifier = GetCompleteRoomIdentifier(endpoint.room(), current_map_name); if (room_identifier) { RoomInfo& room_info = info_.rooms[*room_identifier]; room_info.connections_referenced_by.push_back(human_connection); } else { // Not sure where else to store this right now. std::cout << "A connection used the following malformed room identifier: " << endpoint.room().ShortDebugString() << std::endl; } } else if (endpoint.has_painting()) { auto painting_identifier = GetCompletePaintingIdentifier( endpoint.painting(), current_map_name, std::nullopt); if (painting_identifier) { PaintingInfo& painting_info = info_.paintings[*painting_identifier]; painting_info.connections_referenced_by.push_back(human_connection); } else { // Not sure where else to store this right now. std::cout << "A connection used the following malformed painting identifier: " << endpoint.painting().ShortDebugString() << std::endl; } } else if (endpoint.has_port()) { auto port_identifier = GetCompletePortIdentifier( endpoint.port(), current_map_name, std::nullopt); if (port_identifier) { PortInfo& port_info = info_.ports[*port_identifier]; port_info.connections_referenced_by.push_back(human_connection); } else { // Not sure where else to store this right now. std::cout << "A connection used the following malformed port identifier: " << endpoint.port().ShortDebugString() << std::endl; } } else if (endpoint.has_panel()) { auto panel_identifier = GetCompletePanelIdentifierWithoutAnswer( endpoint.panel(), current_map_name, std::nullopt); if (panel_identifier) { PanelInfo& panel_info = info_.panels[*panel_identifier]; panel_info.connections_referenced_by.push_back(human_connection); if (endpoint.panel().has_answer()) { panel_info.proxies[endpoint.panel().answer()] .connections_referenced_by.push_back(human_connection); } } } } void ProcessProgressivesFile(std::filesystem::path path) { if (!std::filesystem::exists(path)) { return; } auto h_progs = ReadMessageFromFile<HumanProgressives>(path.string()); for (const HumanProgressive& h_prog : h_progs.progressives()) { ProcessProgressive(h_prog); } } void ProcessProgressive(const HumanProgressive& h_prog) { ProgressiveInfo& prog_info = info_.progressives[h_prog.name()]; prog_info.definitions.push_back(h_prog); for (const DoorIdentifier& di : h_prog.doors()) { if (!di.has_map()) { prog_info.malformed_doors.push_back(di); continue; } DoorInfo& door_info = info_.doors[di]; door_info.progressives_referenced_by.push_back(h_prog.name()); } } void ProcessIdsFile(std::filesystem::path path) { auto ids = ReadIdsFromYaml(path.string()); DoorIdentifier di; PanelIdentifier pi; KeyholderIdentifier ki; for (const auto& [map_name, map] : ids.maps()) { di.set_map(map_name); pi.set_map(map_name); ki.set_map(map_name); for (const auto& [door_name, ap_id] : map.doors()) { di.set_name(door_name); DoorInfo& door_info = info_.doors[di]; door_info.has_id = true; } for (const auto& [room_name, room] : map.rooms()) { pi.set_room(room_name); ki.set_room(room_name); for (const auto& [panel_name, ap_id] : room.panels()) { pi.set_name(panel_name); PanelInfo& panel_info = info_.panels[pi]; panel_info.has_id = true; } for (const auto& [mastery_name, ap_id] : room.masteries()) { // TODO: Mastery } for (const auto& [keyholder_name, ap_id] : room.keyholders()) { ki.set_name(keyholder_name); KeyholderInfo& keyholder_info = info_.keyholders[ki]; keyholder_info.has_id = true; } } } for (const auto& [tag, id] : ids.special()) { // TODO: Specials } for (const auto& [letter_name, ap_id] : ids.letters()) { LetterIdentifier li = std::make_tuple(letter_name[0], letter_name[1] == '2'); LetterInfo& letter_info = info_.letters[li]; letter_info.has_id = true; } for (const auto& [ending_name, ap_id] : ids.endings()) { EndingInfo& ending_info = info_.endings[ending_name]; ending_info.has_id = true; } for (const auto& [prog_name, ap_id] : ids.progressives()) { ProgressiveInfo& prog_info = info_.progressives[prog_name]; prog_info.has_id = true; } } std::string mapdir_; CollectedInfo& info_; }; } // namespace void ProcessHumanData(const std::string& mapdir, CollectedInfo& info) { HumanProcessor human_processor(mapdir, info); human_processor.Run(); } } // namespace com::fourisland::lingo2_archipelago