diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-09-08 12:42:31 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-09-08 12:42:31 -0400 |
commit | 6af543ba049e3ba880b113907cd5222b205b8c05 (patch) | |
tree | 58a17c86870db0e67e30e20b7349aee69fba4e82 /apworld | |
parent | 215b576cc816f6f378d057b330ef01f02539602a (diff) | |
download | lingo2-archipelago-6af543ba049e3ba880b113907cd5222b205b8c05.tar.gz lingo2-archipelago-6af543ba049e3ba880b113907cd5222b205b8c05.tar.bz2 lingo2-archipelago-6af543ba049e3ba880b113907cd5222b205b8c05.zip |
Add cyan door behavior option
Diffstat (limited to 'apworld')
-rw-r--r-- | apworld/__init__.py | 1 | ||||
-rw-r--r-- | apworld/options.py | 22 | ||||
-rw-r--r-- | apworld/player_logic.py | 36 |
3 files changed, 49 insertions, 10 deletions
diff --git a/apworld/__init__.py b/apworld/__init__.py index d6a3acb..c45e8b3 100644 --- a/apworld/__init__.py +++ b/apworld/__init__.py | |||
@@ -66,6 +66,7 @@ class Lingo2World(World): | |||
66 | 66 | ||
67 | def fill_slot_data(self): | 67 | def fill_slot_data(self): |
68 | slot_options = [ | 68 | slot_options = [ |
69 | "cyan_door_behavior", | ||
69 | "daedalus_roof_access", | 70 | "daedalus_roof_access", |
70 | "keyholder_sanity", | 71 | "keyholder_sanity", |
71 | "shuffle_control_center_colors", | 72 | "shuffle_control_center_colors", |
diff --git a/apworld/options.py b/apworld/options.py index dbf09e7..2197b0f 100644 --- a/apworld/options.py +++ b/apworld/options.py | |||
@@ -48,6 +48,27 @@ class KeyholderSanity(Toggle): | |||
48 | display_name = "Keyholder Sanity" | 48 | display_name = "Keyholder Sanity" |
49 | 49 | ||
50 | 50 | ||
51 | class CyanDoorBehavior(Choice): | ||
52 | """ | ||
53 | Cyan-colored doors usually only open upon unlocking double letters. Some panels also only appear upon unlocking | ||
54 | double letters. This option determines how these unlocks should behave. | ||
55 | |||
56 | - **Collect H2**: In the base game, H2 is the first double letter you are intended to collect, so cyan doors only | ||
57 | open when you collect the H2 pickup in The Repetitive. Collecting the actual pickup is still required even with | ||
58 | remote letter shuffle enabled. | ||
59 | - **Any Double Letter**: Cyan doors will open when you have unlocked any cyan letter on your keyboard. In letter | ||
60 | shuffle, this means receiving a cyan letter, not picking up a cyan letter collectable. | ||
61 | - **Item**: Cyan doors will be grouped together in a single item. | ||
62 | |||
63 | Note that some cyan doors are impacted by door shuffle (e.g. the entrance to The Tower). When door shuffle is | ||
64 | enabled, these doors won't be affected by the value of this option. | ||
65 | """ | ||
66 | display_name = "Cyan Door Behavior" | ||
67 | option_collect_h2 = 0 | ||
68 | option_any_double_letter = 1 | ||
69 | option_item = 2 | ||
70 | |||
71 | |||
51 | class DaedalusRoofAccess(Toggle): | 72 | class DaedalusRoofAccess(Toggle): |
52 | """ | 73 | """ |
53 | If enabled, the player will be logically expected to be able to go from the castle entrance to any part of Daedalus | 74 | If enabled, the player will be logically expected to be able to go from the castle entrance to any part of Daedalus |
@@ -82,5 +103,6 @@ class Lingo2Options(PerGameCommonOptions): | |||
82 | shuffle_control_center_colors: ShuffleControlCenterColors | 103 | shuffle_control_center_colors: ShuffleControlCenterColors |
83 | shuffle_letters: ShuffleLetters | 104 | shuffle_letters: ShuffleLetters |
84 | keyholder_sanity: KeyholderSanity | 105 | keyholder_sanity: KeyholderSanity |
106 | cyan_door_behavior: CyanDoorBehavior | ||
85 | daedalus_roof_access: DaedalusRoofAccess | 107 | daedalus_roof_access: DaedalusRoofAccess |
86 | victory_condition: VictoryCondition | 108 | victory_condition: VictoryCondition |
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index ce9a4e5..317d13b 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py | |||
@@ -3,7 +3,7 @@ from enum import IntEnum, auto | |||
3 | from .generated import data_pb2 as data_pb2 | 3 | from .generated import data_pb2 as data_pb2 |
4 | from typing import TYPE_CHECKING, NamedTuple | 4 | from typing import TYPE_CHECKING, NamedTuple |
5 | 5 | ||
6 | from .options import VictoryCondition, ShuffleLetters | 6 | from .options import VictoryCondition, ShuffleLetters, CyanDoorBehavior |
7 | 7 | ||
8 | if TYPE_CHECKING: | 8 | if TYPE_CHECKING: |
9 | from . import Lingo2World | 9 | from . import Lingo2World |
@@ -124,11 +124,13 @@ class Lingo2PlayerLogic: | |||
124 | self.real_items.append(progressive.name) | 124 | self.real_items.append(progressive.name) |
125 | 125 | ||
126 | for door_group in world.static_logic.objects.door_groups: | 126 | for door_group in world.static_logic.objects.door_groups: |
127 | if door_group.type == data_pb2.DoorGroupType.CONNECTOR and not self.world.options.shuffle_doors: | 127 | if door_group.type == data_pb2.DoorGroupType.CONNECTOR: |
128 | continue | 128 | if not self.world.options.shuffle_doors: |
129 | 129 | continue | |
130 | if (door_group.type == data_pb2.DoorGroupType.COLOR_CONNECTOR and | 130 | elif door_group.type == data_pb2.DoorGroupType.COLOR_CONNECTOR: |
131 | not self.world.options.shuffle_control_center_colors): | 131 | if not self.world.options.shuffle_control_center_colors: |
132 | continue | ||
133 | else: | ||
132 | continue | 134 | continue |
133 | 135 | ||
134 | for door in door_group.doors: | 136 | for door in door_group.doors: |
@@ -157,6 +159,19 @@ class Lingo2PlayerLogic: | |||
157 | self.item_by_door[door.id] = (door_item_name, 1) | 159 | self.item_by_door[door.id] = (door_item_name, 1) |
158 | self.real_items.append(door_item_name) | 160 | self.real_items.append(door_item_name) |
159 | 161 | ||
162 | # We handle cyan_door_behavior = Item after door shuffle, because cyan doors that are impacted by door shuffle | ||
163 | # should be exempt from cyan_door_behavior. | ||
164 | if world.options.cyan_door_behavior == CyanDoorBehavior.option_item: | ||
165 | for door_group in world.static_logic.objects.door_groups: | ||
166 | if door_group.type != data_pb2.DoorGroupType.CYAN_DOORS: | ||
167 | continue | ||
168 | |||
169 | for door in door_group.doors: | ||
170 | if not door in self.item_by_door: | ||
171 | self.item_by_door[door] = (door_group.name, 1) | ||
172 | |||
173 | self.real_items.append(door_group.name) | ||
174 | |||
160 | for door in world.static_logic.objects.doors: | 175 | for door in world.static_logic.objects.doors: |
161 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: | 176 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: |
162 | self.locations_by_room.setdefault(door.room_id, []).append(PlayerLocation(door.ap_id, | 177 | self.locations_by_room.setdefault(door.room_id, []).append(PlayerLocation(door.ap_id, |
@@ -295,12 +310,13 @@ class Lingo2PlayerLogic: | |||
295 | self.add_solution_reqs(reqs, door.control_center_color) | 310 | self.add_solution_reqs(reqs, door.control_center_color) |
296 | 311 | ||
297 | if door.double_letters: | 312 | if door.double_letters: |
298 | if self.world.options.shuffle_letters in [ShuffleLetters.option_vanilla, | 313 | if self.world.options.cyan_door_behavior == CyanDoorBehavior.option_collect_h2: |
299 | ShuffleLetters.option_vanilla_cyan]: | ||
300 | reqs.rooms.add("The Repetitive - Main Room") | 314 | reqs.rooms.add("The Repetitive - Main Room") |
301 | elif self.world.options.shuffle_letters in [ShuffleLetters.option_progressive, | 315 | elif self.world.options.cyan_door_behavior == CyanDoorBehavior.option_any_double_letter: |
302 | ShuffleLetters.option_item_cyan]: | ||
303 | reqs.cyans = True | 316 | reqs.cyans = True |
317 | elif self.world.options.cyan_door_behavior == CyanDoorBehavior.option_item: | ||
318 | # There shouldn't be any locations that are cyan doors. | ||
319 | pass | ||
304 | 320 | ||
305 | for keyholder_uses in door.keyholders: | 321 | for keyholder_uses in door.keyholders: |
306 | key_name = keyholder_uses.key.upper() | 322 | key_name = keyholder_uses.key.upper() |