diff options
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/pickle_static_data.py | 96 | ||||
| -rw-r--r-- | utils/validate_config.rb | 48 |
2 files changed, 101 insertions, 43 deletions
| diff --git a/utils/pickle_static_data.py b/utils/pickle_static_data.py index 5d6fa1e..10ec69b 100644 --- a/utils/pickle_static_data.py +++ b/utils/pickle_static_data.py | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | from typing import Dict, List, Set | 1 | from typing import Dict, List, Set, Optional |
| 2 | 2 | ||
| 3 | import os | 3 | import os |
| 4 | import sys | 4 | import sys |
| @@ -6,7 +6,8 @@ import sys | |||
| 6 | sys.path.append(os.path.join("worlds", "lingo")) | 6 | sys.path.append(os.path.join("worlds", "lingo")) |
| 7 | sys.path.append(".") | 7 | sys.path.append(".") |
| 8 | sys.path.append("..") | 8 | sys.path.append("..") |
| 9 | from datatypes import Door, Painting, Panel, Progression, Room, RoomAndDoor, RoomAndPanel, RoomEntrance | 9 | from datatypes import Door, DoorType, EntranceType, Painting, Panel, Progression, Room, RoomAndDoor, RoomAndPanel,\ |
| 10 | RoomEntrance | ||
| 10 | 11 | ||
| 11 | import hashlib | 12 | import hashlib |
| 12 | import pickle | 13 | import pickle |
| @@ -28,6 +29,9 @@ PAINTING_EXITS: int = 0 | |||
| 28 | REQUIRED_PAINTING_ROOMS: List[str] = [] | 29 | REQUIRED_PAINTING_ROOMS: List[str] = [] |
| 29 | REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS: List[str] = [] | 30 | REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS: List[str] = [] |
| 30 | 31 | ||
| 32 | SUNWARP_ENTRANCES: List[str] = ["", "", "", "", "", ""] | ||
| 33 | SUNWARP_EXITS: List[str] = ["", "", "", "", "", ""] | ||
| 34 | |||
| 31 | SPECIAL_ITEM_IDS: Dict[str, int] = {} | 35 | SPECIAL_ITEM_IDS: Dict[str, int] = {} |
| 32 | PANEL_LOCATION_IDS: Dict[str, Dict[str, int]] = {} | 36 | PANEL_LOCATION_IDS: Dict[str, Dict[str, int]] = {} |
| 33 | DOOR_LOCATION_IDS: Dict[str, Dict[str, int]] = {} | 37 | DOOR_LOCATION_IDS: Dict[str, Dict[str, int]] = {} |
| @@ -96,41 +100,51 @@ def load_static_data(ll1_path, ids_path): | |||
| 96 | PAINTING_EXITS = len(PAINTING_EXIT_ROOMS) | 100 | PAINTING_EXITS = len(PAINTING_EXIT_ROOMS) |
| 97 | 101 | ||
| 98 | 102 | ||
| 99 | def process_entrance(source_room, doors, room_obj): | 103 | def process_single_entrance(source_room: str, room_name: str, door_obj) -> RoomEntrance: |
| 100 | global PAINTING_ENTRANCES, PAINTING_EXIT_ROOMS | 104 | global PAINTING_ENTRANCES, PAINTING_EXIT_ROOMS |
| 101 | 105 | ||
| 106 | entrance_type = EntranceType.NORMAL | ||
| 107 | if "painting" in door_obj and door_obj["painting"]: | ||
| 108 | entrance_type = EntranceType.PAINTING | ||
| 109 | elif "sunwarp" in door_obj and door_obj["sunwarp"]: | ||
| 110 | entrance_type = EntranceType.SUNWARP | ||
| 111 | elif "warp" in door_obj and door_obj["warp"]: | ||
| 112 | entrance_type = EntranceType.WARP | ||
| 113 | elif source_room == "Crossroads" and room_name == "Roof": | ||
| 114 | entrance_type = EntranceType.CROSSROADS_ROOF_ACCESS | ||
| 115 | |||
| 116 | if "painting" in door_obj and door_obj["painting"]: | ||
| 117 | PAINTING_EXIT_ROOMS.add(room_name) | ||
| 118 | PAINTING_ENTRANCES += 1 | ||
| 119 | |||
| 120 | if "door" in door_obj: | ||
| 121 | return RoomEntrance(source_room, RoomAndDoor( | ||
| 122 | door_obj["room"] if "room" in door_obj else None, | ||
| 123 | door_obj["door"] | ||
| 124 | ), entrance_type) | ||
| 125 | else: | ||
| 126 | return RoomEntrance(source_room, None, entrance_type) | ||
| 127 | |||
| 128 | |||
| 129 | def process_entrance(source_room, doors, room_obj): | ||
| 102 | # If the value of an entrance is just True, that means that the entrance is always accessible. | 130 | # If the value of an entrance is just True, that means that the entrance is always accessible. |
| 103 | if doors is True: | 131 | if doors is True: |
| 104 | room_obj.entrances.append(RoomEntrance(source_room, None, False)) | 132 | room_obj.entrances.append(RoomEntrance(source_room, None, EntranceType.NORMAL)) |
| 105 | elif isinstance(doors, dict): | 133 | elif isinstance(doors, dict): |
| 106 | # If the value of an entrance is a dictionary, that means the entrance requires a door to be accessible, is a | 134 | # If the value of an entrance is a dictionary, that means the entrance requires a door to be accessible, is a |
| 107 | # painting-based entrance, or both. | 135 | # painting-based entrance, or both. |
| 108 | if "painting" in doors and "door" not in doors: | 136 | room_obj.entrances.append(process_single_entrance(source_room, room_obj.name, doors)) |
| 109 | PAINTING_EXIT_ROOMS.add(room_obj.name) | ||
| 110 | PAINTING_ENTRANCES += 1 | ||
| 111 | |||
| 112 | room_obj.entrances.append(RoomEntrance(source_room, None, True)) | ||
| 113 | else: | ||
| 114 | if "painting" in doors and doors["painting"]: | ||
| 115 | PAINTING_EXIT_ROOMS.add(room_obj.name) | ||
| 116 | PAINTING_ENTRANCES += 1 | ||
| 117 | |||
| 118 | room_obj.entrances.append(RoomEntrance(source_room, RoomAndDoor( | ||
| 119 | doors["room"] if "room" in doors else None, | ||
| 120 | doors["door"] | ||
| 121 | ), doors["painting"] if "painting" in doors else False)) | ||
| 122 | else: | 137 | else: |
| 123 | # If the value of an entrance is a list, then there are multiple possible doors that can give access to the | 138 | # If the value of an entrance is a list, then there are multiple possible doors that can give access to the |
| 124 | # entrance. | 139 | # entrance. If there are multiple connections with the same door (or lack of door) that differ only by entrance |
| 140 | # type, coalesce them into one entrance. | ||
| 141 | entrances: Dict[Optional[RoomAndDoor], EntranceType] = {} | ||
| 125 | for door in doors: | 142 | for door in doors: |
| 126 | if "painting" in door and door["painting"]: | 143 | entrance = process_single_entrance(source_room, room_obj.name, door) |
| 127 | PAINTING_EXIT_ROOMS.add(room_obj.name) | 144 | entrances[entrance.door] = entrances.get(entrance.door, EntranceType(0)) | entrance.type |
| 128 | PAINTING_ENTRANCES += 1 | ||
| 129 | 145 | ||
| 130 | room_obj.entrances.append(RoomEntrance(source_room, RoomAndDoor( | 146 | for door, entrance_type in entrances.items(): |
| 131 | door["room"] if "room" in door else None, | 147 | room_obj.entrances.append(RoomEntrance(source_room, door, entrance_type)) |
| 132 | door["door"] | ||
| 133 | ), door["painting"] if "painting" in door else False)) | ||
| 134 | 148 | ||
| 135 | 149 | ||
| 136 | def process_panel(room_name, panel_name, panel_data): | 150 | def process_panel(room_name, panel_name, panel_data): |
| @@ -250,11 +264,6 @@ def process_door(room_name, door_name, door_data): | |||
| 250 | else: | 264 | else: |
| 251 | include_reduce = False | 265 | include_reduce = False |
| 252 | 266 | ||
| 253 | if "junk_item" in door_data: | ||
| 254 | junk_item = door_data["junk_item"] | ||
| 255 | else: | ||
| 256 | junk_item = False | ||
| 257 | |||
| 258 | if "door_group" in door_data: | 267 | if "door_group" in door_data: |
| 259 | door_group = door_data["door_group"] | 268 | door_group = door_data["door_group"] |
| 260 | else: | 269 | else: |
| @@ -276,7 +285,7 @@ def process_door(room_name, door_name, door_data): | |||
| 276 | panels.append(RoomAndPanel(None, panel)) | 285 | panels.append(RoomAndPanel(None, panel)) |
| 277 | else: | 286 | else: |
| 278 | skip_location = True | 287 | skip_location = True |
| 279 | panels = None | 288 | panels = [] |
| 280 | 289 | ||
| 281 | # The location name associated with a door can be explicitly specified in the configuration. If it is not, then the | 290 | # The location name associated with a door can be explicitly specified in the configuration. If it is not, then the |
| 282 | # name is generated using a combination of all of the panels that would ordinarily open the door. This can get quite | 291 | # name is generated using a combination of all of the panels that would ordinarily open the door. This can get quite |
| @@ -312,8 +321,14 @@ def process_door(room_name, door_name, door_data): | |||
| 312 | else: | 321 | else: |
| 313 | painting_ids = [] | 322 | painting_ids = [] |
| 314 | 323 | ||
| 324 | door_type = DoorType.NORMAL | ||
| 325 | if door_name.endswith(" Sunwarp"): | ||
| 326 | door_type = DoorType.SUNWARP | ||
| 327 | elif room_name == "Pilgrim Antechamber" and door_name == "Sun Painting": | ||
| 328 | door_type = DoorType.SUN_PAINTING | ||
| 329 | |||
| 315 | door_obj = Door(door_name, item_name, location_name, panels, skip_location, skip_item, has_doors, | 330 | door_obj = Door(door_name, item_name, location_name, panels, skip_location, skip_item, has_doors, |
| 316 | painting_ids, event, door_group, include_reduce, junk_item, item_group) | 331 | painting_ids, event, door_group, include_reduce, door_type, item_group) |
| 317 | 332 | ||
| 318 | DOORS_BY_ROOM[room_name][door_name] = door_obj | 333 | DOORS_BY_ROOM[room_name][door_name] = door_obj |
| 319 | 334 | ||
| @@ -377,6 +392,15 @@ def process_painting(room_name, painting_data): | |||
| 377 | PAINTINGS[painting_id] = painting_obj | 392 | PAINTINGS[painting_id] = painting_obj |
| 378 | 393 | ||
| 379 | 394 | ||
| 395 | def process_sunwarp(room_name, sunwarp_data): | ||
| 396 | global SUNWARP_ENTRANCES, SUNWARP_EXITS | ||
| 397 | |||
| 398 | if sunwarp_data["direction"] == "enter": | ||
| 399 | SUNWARP_ENTRANCES[sunwarp_data["dots"] - 1] = room_name | ||
| 400 | else: | ||
| 401 | SUNWARP_EXITS[sunwarp_data["dots"] - 1] = room_name | ||
| 402 | |||
| 403 | |||
| 380 | def process_progression(room_name, progression_name, progression_doors): | 404 | def process_progression(room_name, progression_name, progression_doors): |
| 381 | global PROGRESSIVE_ITEMS, PROGRESSION_BY_ROOM | 405 | global PROGRESSIVE_ITEMS, PROGRESSION_BY_ROOM |
| 382 | 406 | ||
| @@ -422,6 +446,10 @@ def process_room(room_name, room_data): | |||
| 422 | for painting_data in room_data["paintings"]: | 446 | for painting_data in room_data["paintings"]: |
| 423 | process_painting(room_name, painting_data) | 447 | process_painting(room_name, painting_data) |
| 424 | 448 | ||
| 449 | if "sunwarps" in room_data: | ||
| 450 | for sunwarp_data in room_data["sunwarps"]: | ||
| 451 | process_sunwarp(room_name, sunwarp_data) | ||
| 452 | |||
| 425 | if "progression" in room_data: | 453 | if "progression" in room_data: |
| 426 | for progression_name, progression_doors in room_data["progression"].items(): | 454 | for progression_name, progression_doors in room_data["progression"].items(): |
| 427 | process_progression(room_name, progression_name, progression_doors) | 455 | process_progression(room_name, progression_name, progression_doors) |
| @@ -468,6 +496,8 @@ if __name__ == '__main__': | |||
| 468 | "PAINTING_EXITS": PAINTING_EXITS, | 496 | "PAINTING_EXITS": PAINTING_EXITS, |
| 469 | "REQUIRED_PAINTING_ROOMS": REQUIRED_PAINTING_ROOMS, | 497 | "REQUIRED_PAINTING_ROOMS": REQUIRED_PAINTING_ROOMS, |
| 470 | "REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS": REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS, | 498 | "REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS": REQUIRED_PAINTING_WHEN_NO_DOORS_ROOMS, |
| 499 | "SUNWARP_ENTRANCES": SUNWARP_ENTRANCES, | ||
| 500 | "SUNWARP_EXITS": SUNWARP_EXITS, | ||
| 471 | "SPECIAL_ITEM_IDS": SPECIAL_ITEM_IDS, | 501 | "SPECIAL_ITEM_IDS": SPECIAL_ITEM_IDS, |
| 472 | "PANEL_LOCATION_IDS": PANEL_LOCATION_IDS, | 502 | "PANEL_LOCATION_IDS": PANEL_LOCATION_IDS, |
| 473 | "DOOR_LOCATION_IDS": DOOR_LOCATION_IDS, | 503 | "DOOR_LOCATION_IDS": DOOR_LOCATION_IDS, |
| diff --git a/utils/validate_config.rb b/utils/validate_config.rb index ae0ac61..831fee2 100644 --- a/utils/validate_config.rb +++ b/utils/validate_config.rb | |||
| @@ -37,12 +37,14 @@ configured_panels = Set[] | |||
| 37 | mentioned_rooms = Set[] | 37 | mentioned_rooms = Set[] |
| 38 | mentioned_doors = Set[] | 38 | mentioned_doors = Set[] |
| 39 | mentioned_panels = Set[] | 39 | mentioned_panels = Set[] |
| 40 | mentioned_sunwarp_entrances = Set[] | ||
| 41 | mentioned_sunwarp_exits = Set[] | ||
| 40 | 42 | ||
| 41 | door_groups = {} | 43 | door_groups = {} |
| 42 | 44 | ||
| 43 | directives = Set["entrances", "panels", "doors", "paintings", "progression"] | 45 | directives = Set["entrances", "panels", "doors", "paintings", "sunwarps", "progression"] |
| 44 | panel_directives = Set["id", "required_room", "required_door", "required_panel", "colors", "check", "exclude_reduce", "tag", "link", "subtag", "achievement", "copy_to_sign", "non_counting", "hunt"] | 46 | panel_directives = Set["id", "required_room", "required_door", "required_panel", "colors", "check", "exclude_reduce", "tag", "link", "subtag", "achievement", "copy_to_sign", "non_counting", "hunt"] |
| 45 | door_directives = Set["id", "painting_id", "panels", "item_name", "item_group", "location_name", "skip_location", "skip_item", "door_group", "include_reduce", "junk_item", "event"] | 47 | door_directives = Set["id", "painting_id", "panels", "item_name", "item_group", "location_name", "skip_location", "skip_item", "door_group", "include_reduce", "event", "warp_id"] |
| 46 | painting_directives = Set["id", "enter_only", "exit_only", "orientation", "required_door", "required", "required_when_no_doors", "move", "req_blocked", "req_blocked_when_no_doors"] | 48 | painting_directives = Set["id", "enter_only", "exit_only", "orientation", "required_door", "required", "required_when_no_doors", "move", "req_blocked", "req_blocked_when_no_doors"] |
| 47 | 49 | ||
| 48 | non_counting = 0 | 50 | non_counting = 0 |
| @@ -67,17 +69,17 @@ config.each do |room_name, room| | |||
| 67 | 69 | ||
| 68 | entrances = [] | 70 | entrances = [] |
| 69 | if entrance.kind_of? Hash | 71 | if entrance.kind_of? Hash |
| 70 | if entrance.keys() != ["painting"] then | 72 | entrances = [entrance] |
| 71 | entrances = [entrance] | ||
| 72 | end | ||
| 73 | elsif entrance.kind_of? Array | 73 | elsif entrance.kind_of? Array |
| 74 | entrances = entrance | 74 | entrances = entrance |
| 75 | end | 75 | end |
| 76 | 76 | ||
| 77 | entrances.each do |e| | 77 | entrances.each do |e| |
| 78 | entrance_room = e.include?("room") ? e["room"] : room_name | 78 | if e.include?("door") then |
| 79 | mentioned_rooms.add(entrance_room) | 79 | entrance_room = e.include?("room") ? e["room"] : room_name |
| 80 | mentioned_doors.add(entrance_room + " - " + e["door"]) | 80 | mentioned_rooms.add(entrance_room) |
| 81 | mentioned_doors.add(entrance_room + " - " + e["door"]) | ||
| 82 | end | ||
| 81 | end | 83 | end |
| 82 | end | 84 | end |
| 83 | 85 | ||
| @@ -204,8 +206,8 @@ config.each do |room_name, room| | |||
| 204 | end | 206 | end |
| 205 | end | 207 | end |
| 206 | 208 | ||
| 207 | if not door.include?("id") and not door.include?("painting_id") and not door["skip_item"] and not door["event"] then | 209 | if not door.include?("id") and not door.include?("painting_id") and not door.include?("warp_id") and not door["skip_item"] and not door["event"] then |
| 208 | puts "#{room_name} - #{door_name} :::: Should be marked skip_item or event if there are no doors or paintings" | 210 | puts "#{room_name} - #{door_name} :::: Should be marked skip_item or event if there are no doors, paintings, or warps" |
| 209 | end | 211 | end |
| 210 | 212 | ||
| 211 | if door.include?("panels") | 213 | if door.include?("panels") |
| @@ -292,6 +294,32 @@ config.each do |room_name, room| | |||
| 292 | end | 294 | end |
| 293 | end | 295 | end |
| 294 | 296 | ||
| 297 | (room["sunwarps"] || []).each do |sunwarp| | ||
| 298 | if sunwarp.include? "dots" and sunwarp.include? "direction" then | ||
| 299 | if sunwarp["dots"] < 1 or sunwarp["dots"] > 6 then | ||
| 300 | puts "#{room_name} :::: Contains a sunwarp with an invalid dots value" | ||
| 301 | end | ||
| 302 | |||
| 303 | if sunwarp["direction"] == "enter" then | ||
| 304 | if mentioned_sunwarp_entrances.include? sunwarp["dots"] then | ||
| 305 | puts "Multiple #{sunwarp["dots"]} sunwarp entrances were found" | ||
| 306 | else | ||
| 307 | mentioned_sunwarp_entrances.add(sunwarp["dots"]) | ||
| 308 | end | ||
| 309 | elsif sunwarp["direction"] == "exit" then | ||
| 310 | if mentioned_sunwarp_exits.include? sunwarp["dots"] then | ||
| 311 | puts "Multiple #{sunwarp["dots"]} sunwarp exits were found" | ||
| 312 | else | ||
| 313 | mentioned_sunwarp_exits.add(sunwarp["dots"]) | ||
| 314 | end | ||
| 315 | else | ||
| 316 | puts "#{room_name} :::: Contains a sunwarp with an invalid direction value" | ||
| 317 | end | ||
| 318 | else | ||
| 319 | puts "#{room_name} :::: Contains a sunwarp without a dots and direction" | ||
| 320 | end | ||
| 321 | end | ||
| 322 | |||
| 295 | (room["progression"] || {}).each do |progression_name, door_list| | 323 | (room["progression"] || {}).each do |progression_name, door_list| |
| 296 | door_list.each do |door| | 324 | door_list.each do |door| |
| 297 | if door.kind_of? Hash then | 325 | if door.kind_of? Hash then |
