about summary refs log tree commit diff stats
path: root/apworld
diff options
context:
space:
mode:
Diffstat (limited to 'apworld')
-rw-r--r--apworld/__init__.py1
-rw-r--r--apworld/client/manager.gd2
-rw-r--r--apworld/client/maps/control_center.gd33
-rw-r--r--apworld/options.py12
-rw-r--r--apworld/player_logic.py8
-rw-r--r--apworld/regions.py4
6 files changed, 59 insertions, 1 deletions
diff --git a/apworld/__init__.py b/apworld/__init__.py index a80156c..6b5338e 100644 --- a/apworld/__init__.py +++ b/apworld/__init__.py
@@ -167,6 +167,7 @@ class Lingo2World(World):
167 167
168 slot_data: dict[str, object] = { 168 slot_data: dict[str, object] = {
169 **self.options.as_dict(*slot_options), 169 **self.options.as_dict(*slot_options),
170 "custom_mint_ending": self.player_logic.custom_mint_ending or "",
170 "rte": [self.static_logic.objects.maps[map_id].name for map_id in self.player_logic.rte_mapping], 171 "rte": [self.static_logic.objects.maps[map_id].name for map_id in self.player_logic.rte_mapping],
171 "seed": self.random.randint(0, 1000000), 172 "seed": self.random.randint(0, 1000000),
172 "version": self.static_logic.get_data_version(), 173 "version": self.static_logic.get_data_version(),
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index e259708..f10a0b7 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd
@@ -67,6 +67,7 @@ const kEndingNameByVictoryValue = {
67} 67}
68 68
69var apworld_version = [0, 0, 0] 69var apworld_version = [0, 0, 0]
70var custom_mint_ending = ""
70var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 71var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2
71var daedalus_only = false 72var daedalus_only = false
72var daedalus_roof_access = false 73var daedalus_roof_access = false
@@ -478,6 +479,7 @@ func _client_connected(slot_data):
478 _last_new_item = localdata[0] 479 _last_new_item = localdata[0]
479 480
480 # Read slot data. 481 # Read slot data.
482 custom_mint_ending = slot_data.get("custom_mint_ending", "")
481 cyan_door_behavior = int(slot_data.get("cyan_door_behavior", 0)) 483 cyan_door_behavior = int(slot_data.get("cyan_door_behavior", 0))
482 daedalus_only = bool(slot_data.get("daedalus_only", false)) 484 daedalus_only = bool(slot_data.get("daedalus_only", false))
483 daedalus_roof_access = bool(slot_data.get("daedalus_roof_access", false)) 485 daedalus_roof_access = bool(slot_data.get("daedalus_roof_access", false))
diff --git a/apworld/client/maps/control_center.gd b/apworld/client/maps/control_center.gd index 1fecc7b..8e919ab 100644 --- a/apworld/client/maps/control_center.gd +++ b/apworld/client/maps/control_center.gd
@@ -96,6 +96,39 @@ func on_map_load(root):
96 sign2.text = "Masteries: %d/%d" % [mastery_count, ap.masteries_requirement] 96 sign2.text = "Masteries: %d/%d" % [mastery_count, ap.masteries_requirement]
97 root.get_node("/root/scene").add_child.call_deferred(sign2) 97 root.get_node("/root/scene").add_child.call_deferred(sign2)
98 98
99 # Handle custom Mint Ending.
100 if ap.custom_mint_ending != "":
101 var panel_prefab = preload("res://objects/nodes/panel.tscn")
102 var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn")
103
104 var mint_ending = root.get_node("/root/scene/Components/Endings/mint_ending")
105
106 var mint_panel = panel_prefab.instantiate()
107 mint_panel.name = "mint_panel"
108 mint_panel.clue = ap.custom_mint_ending
109 mint_panel.symbol = ""
110 mint_panel.answer = ap.custom_mint_ending
111 mint_panel.position = Vector3(-63, 3, -29)
112 mint_panel.rotation_degrees = Vector3(-45, 90, 0)
113 root.get_node("/root/scene").add_child.call_deferred(mint_panel)
114
115 var mint_tpl = tpl_prefab.instantiate()
116 mint_tpl.name = "mint_tpl"
117 mint_tpl.teleport_point = mint_ending.position
118 mint_tpl.teleport_rotate = mint_ending.rotation_degrees
119 mint_tpl.target_path = mint_ending
120 mint_tpl.senders.append(NodePath("/root/scene/mint_panel"))
121 root.get_node("/root/scene").add_child.call_deferred(mint_tpl)
122
123 var mint_tpl2 = tpl_prefab.instantiate()
124 mint_tpl2.name = "mint_tpl2"
125 mint_tpl2.teleport_point = Vector3(0, -1000, 0)
126 mint_tpl2.target_path = mint_panel
127 mint_tpl2.senders.append(NodePath("/root/scene/mint_panel"))
128 root.get_node("/root/scene").add_child.call_deferred(mint_tpl2)
129
130 mint_ending.position.y = -1000
131
99 132
100func _set_up_mastery_listener(root, name): 133func _set_up_mastery_listener(root, name):
101 var prefab = preload("res://objects/nodes/listeners/unlockReaderListener.tscn") 134 var prefab = preload("res://objects/nodes/listeners/unlockReaderListener.tscn")
diff --git a/apworld/options.py b/apworld/options.py index fb159e1..c1eab33 100644 --- a/apworld/options.py +++ b/apworld/options.py
@@ -1,6 +1,6 @@
1from dataclasses import dataclass 1from dataclasses import dataclass
2 2
3from Options import PerGameCommonOptions, Toggle, Choice, DefaultOnToggle, Range, OptionSet 3from Options import PerGameCommonOptions, Toggle, Choice, DefaultOnToggle, Range, OptionSet, FreeText
4 4
5 5
6class ShuffleDoors(DefaultOnToggle): 6class ShuffleDoors(DefaultOnToggle):
@@ -178,6 +178,15 @@ class DaedalusRoofAccess(Toggle):
178 display_name = "Allow Daedalus Roof Access" 178 display_name = "Allow Daedalus Roof Access"
179 179
180 180
181class CustomMintEnding(FreeText):
182 """
183 If not blank, this will add a new panel that must be solved before collecting Mint Ending (EXIT in the Control
184 Center). The panel will only require typing the text provided for this option, which means the choice of letters
185 here has an impact on logic.
186 """
187 display_name = "Custom Mint Ending"
188
189
181class StrictPurpleEnding(DefaultOnToggle): 190class StrictPurpleEnding(DefaultOnToggle):
182 """ 191 """
183 If enabled, the player will be required to have all purple (level 1) letters in order to get Purple Ending. 192 If enabled, the player will be required to have all purple (level 1) letters in order to get Purple Ending.
@@ -280,6 +289,7 @@ class Lingo2Options(PerGameCommonOptions):
280 enable_gift_maps: EnableGiftMaps 289 enable_gift_maps: EnableGiftMaps
281 daedalus_only: DaedalusOnly 290 daedalus_only: DaedalusOnly
282 daedalus_roof_access: DaedalusRoofAccess 291 daedalus_roof_access: DaedalusRoofAccess
292 custom_mint_ending: CustomMintEnding
283 strict_purple_ending: StrictPurpleEnding 293 strict_purple_ending: StrictPurpleEnding
284 strict_cyan_ending: StrictCyanEnding 294 strict_cyan_ending: StrictCyanEnding
285 victory_condition: VictoryCondition 295 victory_condition: VictoryCondition
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index 7bfd49f..ea74266 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py
@@ -223,6 +223,7 @@ class Lingo2PlayerLogic:
223 double_letter_amount: dict[str, int] 223 double_letter_amount: dict[str, int]
224 goal_room_id: int 224 goal_room_id: int
225 rte_mapping: list[int] 225 rte_mapping: list[int]
226 custom_mint_ending: str | None
226 227
227 def __init__(self, world: "Lingo2World"): 228 def __init__(self, world: "Lingo2World"):
228 self.world = world 229 self.world = world
@@ -237,6 +238,7 @@ class Lingo2PlayerLogic:
237 self.real_items = list() 238 self.real_items = list()
238 self.starting_items = list() 239 self.starting_items = list()
239 self.double_letter_amount = dict() 240 self.double_letter_amount = dict()
241 self.custom_mint_ending = None
240 242
241 def should_shuffle_map(game_map) -> bool | set[int]: 243 def should_shuffle_map(game_map) -> bool | set[int]:
242 if world.options.daedalus_only: 244 if world.options.daedalus_only:
@@ -302,6 +304,12 @@ class Lingo2PlayerLogic:
302 raise OptionError(f"When Restrict Letter Placements is enabled and Shuffle Letters is set to Progressive, " 304 raise OptionError(f"When Restrict Letter Placements is enabled and Shuffle Letters is set to Progressive, "
303 f"both Shuffle Doors and Shuffle Symbols must be disabled (Player {world.player}).") 305 f"both Shuffle Doors and Shuffle Symbols must be disabled (Player {world.player}).")
304 306
307 if world.options.custom_mint_ending.value != "":
308 self.custom_mint_ending = ''.join(filter(str.isalpha, world.options.custom_mint_ending.value)).lower()
309
310 if len(self.custom_mint_ending) > 52:
311 raise OptionError(f"Custom Mint Ending should not be greater than 52 letters (Player {world.player}).")
312
305 maximum_masteries = 13 + len(world.options.enable_gift_maps.value) 313 maximum_masteries = 13 + len(world.options.enable_gift_maps.value)
306 if world.options.enable_icarus: 314 if world.options.enable_icarus:
307 maximum_masteries += 1 315 maximum_masteries += 1
diff --git a/apworld/regions.py b/apworld/regions.py index 076c143..3996153 100644 --- a/apworld/regions.py +++ b/apworld/regions.py
@@ -141,6 +141,10 @@ def create_regions(world: "Lingo2World"):
141 if connection.HasField("cyan_ending") and connection.cyan_ending and world.options.strict_cyan_ending: 141 if connection.HasField("cyan_ending") and connection.cyan_ending and world.options.strict_cyan_ending:
142 world.player_logic.add_solution_reqs(reqs, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz") 142 world.player_logic.add_solution_reqs(reqs, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
143 143
144 if (connection.HasField("mint_ending") and connection.mint_ending
145 and world.player_logic.custom_mint_ending is not None):
146 world.player_logic.add_solution_reqs(reqs, world.player_logic.custom_mint_ending)
147
144 reqs.simplify() 148 reqs.simplify()
145 reqs.remove_room(from_region) 149 reqs.remove_room(from_region)
146 150