diff options
25 files changed, 109 insertions, 6 deletions
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index 84c93c8..5271ed1 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py | |||
@@ -73,7 +73,7 @@ class AccessRequirements: | |||
73 | self.cyans = self.cyans or other.cyans | 73 | self.cyans = self.cyans or other.cyans |
74 | 74 | ||
75 | for disjunction in other.or_logic: | 75 | for disjunction in other.or_logic: |
76 | self.or_logic.append(disjunction) | 76 | self.or_logic.append([sub_req.copy() for sub_req in disjunction]) |
77 | 77 | ||
78 | if other.complete_at is not None: | 78 | if other.complete_at is not None: |
79 | # Merging multiple requirements that use complete_at sucks, and is part of why we want to minimize use of | 79 | # Merging multiple requirements that use complete_at sucks, and is part of why we want to minimize use of |
@@ -84,7 +84,7 @@ class AccessRequirements: | |||
84 | 84 | ||
85 | left_req = AccessRequirements() | 85 | left_req = AccessRequirements() |
86 | left_req.complete_at = self.complete_at | 86 | left_req.complete_at = self.complete_at |
87 | left_req.possibilities = self.possibilities | 87 | left_req.possibilities = [sub_req.copy() for sub_req in self.possibilities] |
88 | self.or_logic.append([left_req]) | 88 | self.or_logic.append([left_req]) |
89 | 89 | ||
90 | self.complete_at = None | 90 | self.complete_at = None |
@@ -92,11 +92,11 @@ class AccessRequirements: | |||
92 | 92 | ||
93 | right_req = AccessRequirements() | 93 | right_req = AccessRequirements() |
94 | right_req.complete_at = other.complete_at | 94 | right_req.complete_at = other.complete_at |
95 | right_req.possibilities = other.possibilities | 95 | right_req.possibilities = [sub_req.copy() for sub_req in other.possibilities] |
96 | self.or_logic.append([right_req]) | 96 | self.or_logic.append([right_req]) |
97 | else: | 97 | else: |
98 | self.complete_at = other.complete_at | 98 | self.complete_at = other.complete_at |
99 | self.possibilities = other.possibilities | 99 | self.possibilities = [sub_req.copy() for sub_req in other.possibilities] |
100 | 100 | ||
101 | def is_empty(self) -> bool: | 101 | def is_empty(self) -> bool: |
102 | return (len(self.items) == 0 and len(self.progressives) == 0 and len(self.rooms) == 0 and len(self.letters) == 0 | 102 | return (len(self.items) == 0 and len(self.progressives) == 0 and len(self.rooms) == 0 and len(self.letters) == 0 |
diff --git a/data/maps/the_congruent/metadata.txtpb b/data/maps/the_congruent/metadata.txtpb index 16428c4..6260ed4 100644 --- a/data/maps/the_congruent/metadata.txtpb +++ b/data/maps/the_congruent/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Congruent" | 1 | display_name: "The Congruent" |
2 | worldport_entrance { | ||
3 | room: "Main Area" | ||
4 | name: "DARKROOM" | ||
5 | } | ||
diff --git a/data/maps/the_double_sided/metadata.txtpb b/data/maps/the_double_sided/metadata.txtpb index c354fd8..6f56c63 100644 --- a/data/maps/the_double_sided/metadata.txtpb +++ b/data/maps/the_double_sided/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Double Sided" | 1 | display_name: "The Double Sided" |
2 | worldport_entrance { | ||
3 | room: "Start" | ||
4 | name: "DARKROOM" | ||
5 | } | ||
diff --git a/data/maps/the_jubilant/metadata.txtpb b/data/maps/the_jubilant/metadata.txtpb index 7de7b85..4af1874 100644 --- a/data/maps/the_jubilant/metadata.txtpb +++ b/data/maps/the_jubilant/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Jubilant" | 1 | display_name: "The Jubilant" |
2 | worldport_entrance { | ||
3 | room: "Main Area" | ||
4 | name: "GREAT" | ||
5 | } | ||
diff --git a/data/maps/the_keen/metadata.txtpb b/data/maps/the_keen/metadata.txtpb index 669f608..909f420 100644 --- a/data/maps/the_keen/metadata.txtpb +++ b/data/maps/the_keen/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Keen" | 1 | display_name: "The Keen" |
2 | worldport_entrance { | ||
3 | room: "Main Area" | ||
4 | name: "GREAT" | ||
5 | } | ||
diff --git a/data/maps/the_liberated/metadata.txtpb b/data/maps/the_liberated/metadata.txtpb index a92d7e5..b9b4321 100644 --- a/data/maps/the_liberated/metadata.txtpb +++ b/data/maps/the_liberated/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Liberated" | 1 | display_name: "The Liberated" |
2 | worldport_entrance { | ||
3 | room: "Puzzle Room" | ||
4 | name: "ENTRY" | ||
5 | } | ||
diff --git a/data/maps/the_linear/metadata.txtpb b/data/maps/the_linear/metadata.txtpb index 989463d..838bb2b 100644 --- a/data/maps/the_linear/metadata.txtpb +++ b/data/maps/the_linear/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Linear" | 1 | display_name: "The Linear" |
2 | worldport_entrance { | ||
3 | room: "Room" | ||
4 | name: "GREAT" | ||
5 | } | ||
diff --git a/data/maps/the_lionized/metadata.txtpb b/data/maps/the_lionized/metadata.txtpb index 38fd5c2..8d6168d 100644 --- a/data/maps/the_lionized/metadata.txtpb +++ b/data/maps/the_lionized/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Lionized" | 1 | display_name: "The Lionized" |
2 | worldport_entrance { | ||
3 | room: "Puzzle Room" | ||
4 | name: "ENTRY" | ||
5 | } | ||
diff --git a/data/maps/the_literate/metadata.txtpb b/data/maps/the_literate/metadata.txtpb index 76d1df6..0e04306 100644 --- a/data/maps/the_literate/metadata.txtpb +++ b/data/maps/the_literate/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Literate" | 1 | display_name: "The Literate" |
2 | worldport_entrance { | ||
3 | room: "Puzzle Room" | ||
4 | name: "ENTRY" | ||
5 | } | ||
diff --git a/data/maps/the_lively/metadata.txtpb b/data/maps/the_lively/metadata.txtpb index cbf11c2..acd1177 100644 --- a/data/maps/the_lively/metadata.txtpb +++ b/data/maps/the_lively/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Lively" | 1 | display_name: "The Lively" |
2 | worldport_entrance { | ||
3 | room: "Puzzle Room" | ||
4 | name: "BETWEEN" | ||
5 | } | ||
diff --git a/data/maps/the_nuanced/metadata.txtpb b/data/maps/the_nuanced/metadata.txtpb index 9c39826..4ac9b13 100644 --- a/data/maps/the_nuanced/metadata.txtpb +++ b/data/maps/the_nuanced/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Nuanced" | 1 | display_name: "The Nuanced" |
2 | worldport_entrance { | ||
3 | room: "Main Room" | ||
4 | name: "UNYIELDING" | ||
5 | } | ||
diff --git a/data/maps/the_perceptive/metadata.txtpb b/data/maps/the_perceptive/metadata.txtpb index e0c64fb..6942cab 100644 --- a/data/maps/the_perceptive/metadata.txtpb +++ b/data/maps/the_perceptive/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Perceptive" | 1 | display_name: "The Perceptive" |
2 | worldport_entrance { | ||
3 | room: "Main Area" | ||
4 | name: "CC" | ||
5 | } | ||
diff --git a/data/maps/the_quiet/metadata.txtpb b/data/maps/the_quiet/metadata.txtpb index 1fa2c46..d7fd0eb 100644 --- a/data/maps/the_quiet/metadata.txtpb +++ b/data/maps/the_quiet/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Quiet" | 1 | display_name: "The Quiet" |
2 | worldport_entrance { | ||
3 | room: "Main Area" | ||
4 | name: "DAEDALUS" | ||
5 | } | ||
diff --git a/data/maps/the_sirenic/metadata.txtpb b/data/maps/the_sirenic/metadata.txtpb index 19e26a3..80b1783 100644 --- a/data/maps/the_sirenic/metadata.txtpb +++ b/data/maps/the_sirenic/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Sirenic" | 1 | display_name: "The Sirenic" |
2 | worldport_entrance { | ||
3 | room: "Start" | ||
4 | name: "PLAZA" | ||
5 | } | ||
diff --git a/data/maps/the_sun_temple/metadata.txtpb b/data/maps/the_sun_temple/metadata.txtpb index 97f9290..25ed636 100644 --- a/data/maps/the_sun_temple/metadata.txtpb +++ b/data/maps/the_sun_temple/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Sun Temple" | 1 | display_name: "The Sun Temple" |
2 | worldport_entrance { | ||
3 | room: "Entrance" | ||
4 | name: "UNKEMPT" | ||
5 | } | ||
diff --git a/data/maps/the_symbolic/metadata.txtpb b/data/maps/the_symbolic/metadata.txtpb index 311dead..2b37985 100644 --- a/data/maps/the_symbolic/metadata.txtpb +++ b/data/maps/the_symbolic/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Symbolic" | 1 | display_name: "The Symbolic" |
2 | worldport_entrance { | ||
3 | room: "White Room" | ||
4 | name: "PLAZA" | ||
5 | } | ||
diff --git a/data/maps/the_talented/metadata.txtpb b/data/maps/the_talented/metadata.txtpb index 16aa221..943bc69 100644 --- a/data/maps/the_talented/metadata.txtpb +++ b/data/maps/the_talented/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Talented" | 1 | display_name: "The Talented" |
2 | worldport_entrance { | ||
3 | room: "Main Area" | ||
4 | name: "GREAT" | ||
5 | } | ||
diff --git a/data/maps/the_tower/metadata.txtpb b/data/maps/the_tower/metadata.txtpb index dc185e0..3876206 100644 --- a/data/maps/the_tower/metadata.txtpb +++ b/data/maps/the_tower/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Tower" | 1 | display_name: "The Tower" |
2 | worldport_entrance { | ||
3 | room: "First Floor" | ||
4 | name: "GREAT" | ||
5 | } | ||
diff --git a/data/maps/the_wondrous/metadata.txtpb b/data/maps/the_wondrous/metadata.txtpb index 0b96cf2..1c8e04c 100644 --- a/data/maps/the_wondrous/metadata.txtpb +++ b/data/maps/the_wondrous/metadata.txtpb | |||
@@ -1 +1,5 @@ | |||
1 | display_name: "The Wondrous" | 1 | display_name: "The Wondrous" |
2 | worldport_entrance { | ||
3 | room: "Entry" | ||
4 | name: "DAEDALUS" | ||
5 | } | ||
diff --git a/proto/data.proto b/proto/data.proto index d79f47d..a9e1d0d 100644 --- a/proto/data.proto +++ b/proto/data.proto | |||
@@ -264,6 +264,7 @@ message Map { | |||
264 | optional uint64 id = 1; | 264 | optional uint64 id = 1; |
265 | optional string name = 2; | 265 | optional string name = 2; |
266 | optional string display_name = 3; | 266 | optional string display_name = 3; |
267 | optional uint64 worldport_entrance = 4; | ||
267 | } | 268 | } |
268 | 269 | ||
269 | message Progressive { | 270 | message Progressive { |
diff --git a/proto/human.proto b/proto/human.proto index 8e7767a..c8d653f 100644 --- a/proto/human.proto +++ b/proto/human.proto | |||
@@ -217,6 +217,7 @@ message HumanRoom { | |||
217 | message HumanMap { | 217 | message HumanMap { |
218 | optional string display_name = 1; | 218 | optional string display_name = 1; |
219 | repeated string excluded_nodes = 2; | 219 | repeated string excluded_nodes = 2; |
220 | optional PortIdentifier worldport_entrance = 3; | ||
220 | } | 221 | } |
221 | 222 | ||
222 | message HumanProgressive { | 223 | message HumanProgressive { |
diff --git a/tools/datapacker/main.cpp b/tools/datapacker/main.cpp index e807d74..9b487e4 100644 --- a/tools/datapacker/main.cpp +++ b/tools/datapacker/main.cpp | |||
@@ -91,6 +91,13 @@ class DataPacker { | |||
91 | if (metadata.has_display_name()) { | 91 | if (metadata.has_display_name()) { |
92 | map.set_display_name(metadata.display_name()); | 92 | map.set_display_name(metadata.display_name()); |
93 | } | 93 | } |
94 | |||
95 | if (metadata.has_worldport_entrance()) { | ||
96 | map.set_worldport_entrance(container_.FindOrAddPort( | ||
97 | metadata.worldport_entrance().map(), | ||
98 | metadata.worldport_entrance().room(), | ||
99 | metadata.worldport_entrance().name(), map_name, std::nullopt)); | ||
100 | } | ||
94 | } | 101 | } |
95 | 102 | ||
96 | void ProcessRooms(std::filesystem::path path, | 103 | void ProcessRooms(std::filesystem::path path, |
diff --git a/tools/validator/human_processor.cpp b/tools/validator/human_processor.cpp index 2c978bf..de80db0 100644 --- a/tools/validator/human_processor.cpp +++ b/tools/validator/human_processor.cpp | |||
@@ -77,6 +77,17 @@ class HumanProcessor { | |||
77 | for (const std::string& path : metadata.excluded_nodes()) { | 77 | for (const std::string& path : metadata.excluded_nodes()) { |
78 | map_info.game_nodes[path].uses++; | 78 | map_info.game_nodes[path].uses++; |
79 | } | 79 | } |
80 | |||
81 | if (metadata.has_worldport_entrance()) { | ||
82 | auto port_identifier = GetCompletePortIdentifier( | ||
83 | metadata.worldport_entrance(), current_map_name, std::nullopt); | ||
84 | if (port_identifier) { | ||
85 | PortInfo& port_info = info_.ports[*port_identifier]; | ||
86 | port_info.map_worldport_entrances.push_back(current_map_name); | ||
87 | } else { | ||
88 | map_info.malformed_worldport_entrance = metadata.worldport_entrance(); | ||
89 | } | ||
90 | } | ||
80 | } | 91 | } |
81 | 92 | ||
82 | void ProcessRooms(std::filesystem::path path, | 93 | void ProcessRooms(std::filesystem::path path, |
diff --git a/tools/validator/structs.h b/tools/validator/structs.h index d1d45f2..a6787cf 100644 --- a/tools/validator/structs.h +++ b/tools/validator/structs.h | |||
@@ -27,6 +27,8 @@ 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::optional<PortIdentifier> malformed_worldport_entrance; | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | struct RoomInfo { | 34 | struct RoomInfo { |
@@ -57,6 +59,7 @@ struct PortInfo { | |||
57 | 59 | ||
58 | std::vector<HumanConnection> connections_referenced_by; | 60 | std::vector<HumanConnection> connections_referenced_by; |
59 | std::vector<HumanConnection> target_connections_referenced_by; | 61 | std::vector<HumanConnection> target_connections_referenced_by; |
62 | std::vector<std::string> map_worldport_entrances; | ||
60 | }; | 63 | }; |
61 | 64 | ||
62 | struct PaintingInfo { | 65 | struct PaintingInfo { |
diff --git a/tools/validator/validator.cpp b/tools/validator/validator.cpp index 93efdc6..c048bab 100644 --- a/tools/validator/validator.cpp +++ b/tools/validator/validator.cpp | |||
@@ -69,6 +69,11 @@ class Validator { | |||
69 | << " is not defined in the game file." << std::endl; | 69 | << " is not defined in the game file." << std::endl; |
70 | } | 70 | } |
71 | } | 71 | } |
72 | |||
73 | if (map_info.malformed_worldport_entrance) { | ||
74 | std::cout << "The worldport entrance for map " << map_name | ||
75 | << " is malformed." << std::endl; | ||
76 | } | ||
72 | } | 77 | } |
73 | 78 | ||
74 | void ValidateRoom(const RoomIdentifier& room_identifier, | 79 | void ValidateRoom(const RoomIdentifier& room_identifier, |
@@ -253,6 +258,10 @@ class Validator { | |||
253 | std::cout << " CONNECTION " << connection.ShortDebugString() | 258 | std::cout << " CONNECTION " << connection.ShortDebugString() |
254 | << std::endl; | 259 | << std::endl; |
255 | } | 260 | } |
261 | |||
262 | for (const std::string& map_name : port_info.map_worldport_entrances) { | ||
263 | std::cout << " MAP (worldport_entrance) " << map_name << std::endl; | ||
264 | } | ||
256 | } else if (port_info.definitions.size() > 1) { | 265 | } else if (port_info.definitions.size() > 1) { |
257 | std::cout << "Port " << port_identifier.ShortDebugString() | 266 | std::cout << "Port " << port_identifier.ShortDebugString() |
258 | << " was defined multiple times." << std::endl; | 267 | << " was defined multiple times." << std::endl; |
@@ -283,8 +292,7 @@ class Validator { | |||
283 | } | 292 | } |
284 | if (!port.has_rotation()) { | 293 | if (!port.has_rotation()) { |
285 | std::cout << "Port " << port_identifier.ShortDebugString() | 294 | std::cout << "Port " << port_identifier.ShortDebugString() |
286 | << " is shuffleable and missing a rotation." | 295 | << " is shuffleable and missing a rotation." << std::endl; |
287 | << std::endl; | ||
288 | } | 296 | } |
289 | } | 297 | } |
290 | } | 298 | } |