diff options
| -rw-r--r-- | data/LL1.yaml | 1 | ||||
| -rw-r--r-- | player_logic.py | 38 | ||||
| -rw-r--r-- | test/TestDoors.py | 10 | ||||
| -rw-r--r-- | test/TestOrangeTower.py | 4 | ||||
| -rw-r--r-- | test/TestProgressive.py | 6 | ||||
| -rw-r--r-- | test/__init__.py | 9 |
6 files changed, 27 insertions, 41 deletions
| diff --git a/data/LL1.yaml b/data/LL1.yaml index 1a149f2..f72e63c 100644 --- a/data/LL1.yaml +++ b/data/LL1.yaml | |||
| @@ -112,6 +112,7 @@ | |||
| 112 | HI: | 112 | HI: |
| 113 | id: Entry Room/Panel_hi_hi | 113 | id: Entry Room/Panel_hi_hi |
| 114 | tag: midwhite | 114 | tag: midwhite |
| 115 | check: True | ||
| 115 | HIDDEN: | 116 | HIDDEN: |
| 116 | id: Entry Room/Panel_hidden_hidden | 117 | id: Entry Room/Panel_hidden_hidden |
| 117 | tag: midwhite | 118 | tag: midwhite |
| diff --git a/player_logic.py b/player_logic.py index 0ae3035..3a6eedf 100644 --- a/player_logic.py +++ b/player_logic.py | |||
| @@ -248,30 +248,44 @@ class LingoPlayerLogic: | |||
| 248 | "kind of logic error.") | 248 | "kind of logic error.") |
| 249 | 249 | ||
| 250 | if door_shuffle != ShuffleDoors.option_none and location_classification != LocationClassification.insanity \ | 250 | if door_shuffle != ShuffleDoors.option_none and location_classification != LocationClassification.insanity \ |
| 251 | and not early_color_hallways: | 251 | and not early_color_hallways and world.multiworld.players > 1: |
| 252 | # If shuffle doors is on, force a useful item onto the HI panel. This may not necessarily get you out of BK, | 252 | # Under the combination of door shuffle, normal location checks, and no early color hallways, sphere 1 is |
| 253 | # but the goal is to allow you to reach at least one more check. The non-painting ones are hardcoded right | 253 | # only three checks. In a multiplayer situation, this can be frustrating for the player because they are |
| 254 | # now. We only allow the entrance to the Pilgrim Room if color shuffle is off, because otherwise there are | 254 | # more likely to be stuck in the starting room for a long time. To remedy this, we will force a useful item |
| 255 | # no extra checks in there. We only include the entrance to the Rhyme Room when color shuffle is off and | 255 | # onto the GOOD LUCK check under these circumstances. The goal is to expand sphere 1 to at least four |
| 256 | # door shuffle is on simple, because otherwise there are no extra checks in there. | 256 | # checks (and likely more than that). |
| 257 | # | ||
| 258 | # Note: A very low LEVEL 2 requirement would naturally expand sphere 1 to four checks, but this is a very | ||
| 259 | # uncommon configuration, so we will ignore it and force a good item anyway. | ||
| 260 | |||
| 261 | # Starting Room - Back Right Door gives access to OPEN and DEAD END. | ||
| 262 | # Starting Room - Exit Door gives access to OPEN and TRACE. | ||
| 257 | good_item_options: List[str] = ["Starting Room - Back Right Door", "Second Room - Exit Door"] | 263 | good_item_options: List[str] = ["Starting Room - Back Right Door", "Second Room - Exit Door"] |
| 258 | 264 | ||
| 259 | if not color_shuffle: | 265 | if not color_shuffle: |
| 266 | # HOT CRUST and THIS. | ||
| 260 | good_item_options.append("Pilgrim Room - Sun Painting") | 267 | good_item_options.append("Pilgrim Room - Sun Painting") |
| 261 | 268 | ||
| 262 | if door_shuffle == ShuffleDoors.option_simple: | 269 | if door_shuffle == ShuffleDoors.option_simple: |
| 263 | good_item_options += ["Welcome Back Doors"] | 270 | # WELCOME BACK, CLOCKWISE, and DRAWL + RUNS. |
| 271 | good_item_options.append("Welcome Back Doors") | ||
| 272 | else: | ||
| 273 | # WELCOME BACK and CLOCKWISE. | ||
| 274 | good_item_options.append("Welcome Back Area - Shortcut to Starting Room") | ||
| 264 | 275 | ||
| 265 | if not color_shuffle: | 276 | if door_shuffle == ShuffleDoors.option_simple: |
| 266 | good_item_options.append("Rhyme Room Doors") | 277 | # Color hallways access (NOTE: reconsider when sunwarp shuffling exists). |
| 267 | else: | 278 | good_item_options.append("Rhyme Room Doors") |
| 268 | good_item_options += ["Welcome Back Area - Shortcut to Starting Room"] | ||
| 269 | 279 | ||
| 280 | # When painting shuffle is off, most Starting Room paintings give color hallways access. The Wondrous's | ||
| 281 | # painting does not, but it gives access to SHRINK and WELCOME BACK. | ||
| 270 | for painting_obj in PAINTINGS_BY_ROOM["Starting Room"]: | 282 | for painting_obj in PAINTINGS_BY_ROOM["Starting Room"]: |
| 271 | if not painting_obj.enter_only or painting_obj.required_door is None: | 283 | if not painting_obj.enter_only or painting_obj.required_door is None: |
| 272 | continue | 284 | continue |
| 273 | 285 | ||
| 274 | # If painting shuffle is on, we only want to consider paintings that actually go somewhere. | 286 | # If painting shuffle is on, we only want to consider paintings that actually go somewhere. |
| 287 | # | ||
| 288 | # NOTE: This does not guarantee that there will be any checks on the other side. | ||
| 275 | if painting_shuffle and painting_obj.id not in self.painting_mapping.keys(): | 289 | if painting_shuffle and painting_obj.id not in self.painting_mapping.keys(): |
| 276 | continue | 290 | continue |
| 277 | 291 | ||
| diff --git a/test/TestDoors.py b/test/TestDoors.py index 49a0f9c..f496c5f 100644 --- a/test/TestDoors.py +++ b/test/TestDoors.py | |||
| @@ -8,8 +8,6 @@ class TestRequiredRoomLogic(LingoTestBase): | |||
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | def test_pilgrim_first(self) -> None: | 10 | def test_pilgrim_first(self) -> None: |
| 11 | self.remove_forced_good_item() | ||
| 12 | |||
| 13 | self.assertFalse(self.multiworld.state.can_reach("The Seeker", "Region", self.player)) | 11 | self.assertFalse(self.multiworld.state.can_reach("The Seeker", "Region", self.player)) |
| 14 | self.assertFalse(self.multiworld.state.can_reach("Pilgrim Antechamber", "Region", self.player)) | 12 | self.assertFalse(self.multiworld.state.can_reach("Pilgrim Antechamber", "Region", self.player)) |
| 15 | self.assertFalse(self.multiworld.state.can_reach("Pilgrim Room", "Region", self.player)) | 13 | self.assertFalse(self.multiworld.state.can_reach("Pilgrim Room", "Region", self.player)) |
| @@ -30,8 +28,6 @@ class TestRequiredRoomLogic(LingoTestBase): | |||
| 30 | self.assertTrue(self.can_reach_location("The Seeker - Achievement")) | 28 | self.assertTrue(self.can_reach_location("The Seeker - Achievement")) |
| 31 | 29 | ||
| 32 | def test_hidden_first(self) -> None: | 30 | def test_hidden_first(self) -> None: |
| 33 | self.remove_forced_good_item() | ||
| 34 | |||
| 35 | self.assertFalse(self.multiworld.state.can_reach("The Seeker", "Region", self.player)) | 31 | self.assertFalse(self.multiworld.state.can_reach("The Seeker", "Region", self.player)) |
| 36 | self.assertFalse(self.multiworld.state.can_reach("Pilgrim Room", "Region", self.player)) | 32 | self.assertFalse(self.multiworld.state.can_reach("Pilgrim Room", "Region", self.player)) |
| 37 | self.assertFalse(self.can_reach_location("The Seeker - Achievement")) | 33 | self.assertFalse(self.can_reach_location("The Seeker - Achievement")) |
| @@ -59,8 +55,6 @@ class TestRequiredDoorLogic(LingoTestBase): | |||
| 59 | } | 55 | } |
| 60 | 56 | ||
| 61 | def test_through_rhyme(self) -> None: | 57 | def test_through_rhyme(self) -> None: |
| 62 | self.remove_forced_good_item() | ||
| 63 | |||
| 64 | self.assertFalse(self.can_reach_location("Rhyme Room - Circle/Looped Square Wall")) | 58 | self.assertFalse(self.can_reach_location("Rhyme Room - Circle/Looped Square Wall")) |
| 65 | 59 | ||
| 66 | self.collect_by_name("Starting Room - Rhyme Room Entrance") | 60 | self.collect_by_name("Starting Room - Rhyme Room Entrance") |
| @@ -70,8 +64,6 @@ class TestRequiredDoorLogic(LingoTestBase): | |||
| 70 | self.assertTrue(self.can_reach_location("Rhyme Room - Circle/Looped Square Wall")) | 64 | self.assertTrue(self.can_reach_location("Rhyme Room - Circle/Looped Square Wall")) |
| 71 | 65 | ||
| 72 | def test_through_hidden(self) -> None: | 66 | def test_through_hidden(self) -> None: |
| 73 | self.remove_forced_good_item() | ||
| 74 | |||
| 75 | self.assertFalse(self.can_reach_location("Rhyme Room - Circle/Looped Square Wall")) | 67 | self.assertFalse(self.can_reach_location("Rhyme Room - Circle/Looped Square Wall")) |
| 76 | 68 | ||
| 77 | self.collect_by_name("Starting Room - Rhyme Room Entrance") | 69 | self.collect_by_name("Starting Room - Rhyme Room Entrance") |
| @@ -91,8 +83,6 @@ class TestSimpleDoors(LingoTestBase): | |||
| 91 | } | 83 | } |
| 92 | 84 | ||
| 93 | def test_requirement(self): | 85 | def test_requirement(self): |
| 94 | self.remove_forced_good_item() | ||
| 95 | |||
| 96 | self.assertFalse(self.multiworld.state.can_reach("Outside The Wanderer", "Region", self.player)) | 86 | self.assertFalse(self.multiworld.state.can_reach("Outside The Wanderer", "Region", self.player)) |
| 97 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Third Floor", "Region", self.player)) | 87 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Third Floor", "Region", self.player)) |
| 98 | 88 | ||
| diff --git a/test/TestOrangeTower.py b/test/TestOrangeTower.py index 9170de1..7b0c3bb 100644 --- a/test/TestOrangeTower.py +++ b/test/TestOrangeTower.py | |||
| @@ -8,8 +8,6 @@ class TestProgressiveOrangeTower(LingoTestBase): | |||
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | def test_from_welcome_back(self) -> None: | 10 | def test_from_welcome_back(self) -> None: |
| 11 | self.remove_forced_good_item() | ||
| 12 | |||
| 13 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower First Floor", "Region", self.player)) | 11 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower First Floor", "Region", self.player)) |
| 14 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Second Floor", "Region", self.player)) | 12 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Second Floor", "Region", self.player)) |
| 15 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Third Floor", "Region", self.player)) | 13 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Third Floor", "Region", self.player)) |
| @@ -85,8 +83,6 @@ class TestProgressiveOrangeTower(LingoTestBase): | |||
| 85 | self.assertTrue(self.multiworld.state.can_reach("Orange Tower Seventh Floor", "Region", self.player)) | 83 | self.assertTrue(self.multiworld.state.can_reach("Orange Tower Seventh Floor", "Region", self.player)) |
| 86 | 84 | ||
| 87 | def test_from_hub_room(self) -> None: | 85 | def test_from_hub_room(self) -> None: |
| 88 | self.remove_forced_good_item() | ||
| 89 | |||
| 90 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower First Floor", "Region", self.player)) | 86 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower First Floor", "Region", self.player)) |
| 91 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Second Floor", "Region", self.player)) | 87 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Second Floor", "Region", self.player)) |
| 92 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Third Floor", "Region", self.player)) | 88 | self.assertFalse(self.multiworld.state.can_reach("Orange Tower Third Floor", "Region", self.player)) |
| diff --git a/test/TestProgressive.py b/test/TestProgressive.py index 081d674..e79fd6b 100644 --- a/test/TestProgressive.py +++ b/test/TestProgressive.py | |||
| @@ -7,8 +7,6 @@ class TestComplexProgressiveHallwayRoom(LingoTestBase): | |||
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | def test_item(self): | 9 | def test_item(self): |
| 10 | self.remove_forced_good_item() | ||
| 11 | |||
| 12 | self.assertFalse(self.multiworld.state.can_reach("Outside The Agreeable", "Region", self.player)) | 10 | self.assertFalse(self.multiworld.state.can_reach("Outside The Agreeable", "Region", self.player)) |
| 13 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (2)", "Region", self.player)) | 11 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (2)", "Region", self.player)) |
| 14 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (3)", "Region", self.player)) | 12 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (3)", "Region", self.player)) |
| @@ -60,8 +58,6 @@ class TestSimpleHallwayRoom(LingoTestBase): | |||
| 60 | } | 58 | } |
| 61 | 59 | ||
| 62 | def test_item(self): | 60 | def test_item(self): |
| 63 | self.remove_forced_good_item() | ||
| 64 | |||
| 65 | self.assertFalse(self.multiworld.state.can_reach("Outside The Agreeable", "Region", self.player)) | 61 | self.assertFalse(self.multiworld.state.can_reach("Outside The Agreeable", "Region", self.player)) |
| 66 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (2)", "Region", self.player)) | 62 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (2)", "Region", self.player)) |
| 67 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (3)", "Region", self.player)) | 63 | self.assertFalse(self.multiworld.state.can_reach("Hallway Room (3)", "Region", self.player)) |
| @@ -90,8 +86,6 @@ class TestProgressiveArtGallery(LingoTestBase): | |||
| 90 | } | 86 | } |
| 91 | 87 | ||
| 92 | def test_item(self): | 88 | def test_item(self): |
| 93 | self.remove_forced_good_item() | ||
| 94 | |||
| 95 | self.assertFalse(self.multiworld.state.can_reach("Art Gallery", "Region", self.player)) | 89 | self.assertFalse(self.multiworld.state.can_reach("Art Gallery", "Region", self.player)) |
| 96 | self.assertFalse(self.multiworld.state.can_reach("Art Gallery (Second Floor)", "Region", self.player)) | 90 | self.assertFalse(self.multiworld.state.can_reach("Art Gallery (Second Floor)", "Region", self.player)) |
| 97 | self.assertFalse(self.multiworld.state.can_reach("Art Gallery (Third Floor)", "Region", self.player)) | 91 | self.assertFalse(self.multiworld.state.can_reach("Art Gallery (Third Floor)", "Region", self.player)) |
| diff --git a/test/__init__.py b/test/__init__.py index 7ff456d..a4196de 100644 --- a/test/__init__.py +++ b/test/__init__.py | |||
| @@ -6,12 +6,3 @@ from test.bases import WorldTestBase | |||
| 6 | class LingoTestBase(WorldTestBase): | 6 | class LingoTestBase(WorldTestBase): |
| 7 | game = "Lingo" | 7 | game = "Lingo" |
| 8 | player: ClassVar[int] = 1 | 8 | player: ClassVar[int] = 1 |
| 9 | |||
| 10 | def world_setup(self, *args, **kwargs): | ||
| 11 | super().world_setup(*args, **kwargs) | ||
| 12 | |||
| 13 | def remove_forced_good_item(self): | ||
| 14 | location = self.multiworld.get_location("Second Room - Good Luck", self.player) | ||
| 15 | self.remove(location.item) | ||
| 16 | self.multiworld.itempool.append(location.item) | ||
| 17 | self.multiworld.state.events.add(location) | ||
