diff --git a/BaseClasses.py b/BaseClasses.py index f1e5e338999f..4f87c0e4f32c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -997,19 +997,15 @@ def count_group_unique(self, item_name_group: str, player: int) -> int: ) # Item related - def collect(self, item: Item, event: bool = False, location: Optional[Location] = None) -> bool: + def collect(self, item: Item, prevent_sweep: bool = False, location: Optional[Location] = None) -> bool: if location: self.locations_checked.add(location) changed = self.multiworld.worlds[item.player].collect(self, item) - if not changed and event: - self.prog_items[item.player][item.name] += 1 - changed = True - self.stale[item.player] = True - if changed and not event: + if changed and not prevent_sweep: self.sweep_for_events() return changed @@ -1561,7 +1557,7 @@ def get_path(state: CollectionState, region: Region) -> List[Union[Tuple[str, st # Maybe move the big bomb over to the Event system instead? if any(exit_path == 'Pyramid Fairy' for path in self.paths.values() for (_, exit_path) in path): - if multiworld.mode[player] != 'inverted': + if multiworld.worlds[player].options.mode != 'inverted': self.paths[str(multiworld.get_region('Big Bomb Shop', player))] = \ get_path(state, multiworld.get_region('Big Bomb Shop', player)) else: diff --git a/Fill.py b/Fill.py index 5185bbb60ee4..15d5842e2904 100644 --- a/Fill.py +++ b/Fill.py @@ -12,7 +12,12 @@ class FillError(RuntimeError): - pass + def __init__(self, *args: typing.Union[str, typing.Any], **kwargs) -> None: + if "multiworld" in kwargs and isinstance(args[0], str): + placements = (args[0] + f"\nAll Placements:\n" + + f"{[(loc, loc.item) for loc in kwargs['multiworld'].get_filled_locations()]}") + args = (placements, *args[1:]) + super().__init__(*args) def _log_fill_progress(name: str, placed: int, total_items: int) -> None: @@ -212,7 +217,7 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati f"Unfilled locations:\n" f"{', '.join(str(location) for location in locations)}\n" f"Already placed {len(placements)}:\n" - f"{', '.join(str(place) for place in placements)}") + f"{', '.join(str(place) for place in placements)}", multiworld=multiworld) item_pool.extend(unplaced_items) @@ -299,7 +304,7 @@ def remaining_fill(multiworld: MultiWorld, f"Unfilled locations:\n" f"{', '.join(str(location) for location in locations)}\n" f"Already placed {len(placements)}:\n" - f"{', '.join(str(place) for place in placements)}") + f"{', '.join(str(place) for place in placements)}", multiworld=multiworld) itempool.extend(unplaced_items) @@ -506,7 +511,8 @@ def mark_for_locking(location: Location): if progitempool: raise FillError( f"Not enough locations for progression items. " - f"There are {len(progitempool)} more progression items than there are available locations." + f"There are {len(progitempool)} more progression items than there are available locations.", + multiworld=multiworld, ) accessibility_corrections(multiworld, multiworld.state, defaultlocations) @@ -523,7 +529,8 @@ def mark_for_locking(location: Location): if excludedlocations: raise FillError( f"Not enough filler items for excluded locations. " - f"There are {len(excludedlocations)} more excluded locations than filler or trap items." + f"There are {len(excludedlocations)} more excluded locations than filler or trap items.", + multiworld=multiworld, ) restitempool = filleritempool + usefulitempool @@ -589,7 +596,7 @@ def flood_items(multiworld: MultiWorld) -> None: if candidate_item_to_place is not None: item_to_place = candidate_item_to_place else: - raise FillError('No more progress items left to place.') + raise FillError('No more progress items left to place.', multiworld=multiworld) # find item to replace with progress item location_list = multiworld.get_reachable_locations() diff --git a/Launcher.py b/Launcher.py index e4b65be93a68..6b66b2a3a671 100644 --- a/Launcher.py +++ b/Launcher.py @@ -266,7 +266,7 @@ def _on_drop_file(self, window: Window, filename: bytes, x: int, y: int) -> None if file and component: run_component(component, file) else: - logging.warning(f"unable to identify component for {filename}") + logging.warning(f"unable to identify component for {file}") def _stop(self, *largs): # ran into what appears to be https://groups.google.com/g/kivy-users/c/saWDLoYCSZ4 with PyCharm. diff --git a/Main.py b/Main.py index ce054dcd393f..edae5d7b19b1 100644 --- a/Main.py +++ b/Main.py @@ -11,7 +11,8 @@ import worlds from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld, Region -from Fill import balance_multiworld_progression, distribute_items_restrictive, distribute_planned, flood_items +from Fill import FillError, balance_multiworld_progression, distribute_items_restrictive, distribute_planned, \ + flood_items from Options import StartInventoryPool from Utils import __version__, output_path, version_tuple, get_settings from settings import get_settings @@ -151,6 +152,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No # Because some worlds don't actually create items during create_items this has to be as late as possible. if any(getattr(multiworld.worlds[player].options, "start_inventory_from_pool", None) for player in multiworld.player_ids): new_items: List[Item] = [] + old_items: List[Item] = [] depletion_pool: Dict[int, Dict[str, int]] = { player: getattr(multiworld.worlds[player].options, "start_inventory_from_pool", @@ -169,20 +171,24 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No depletion_pool[item.player][item.name] -= 1 # quick abort if we have found all items if not target: - new_items.extend(multiworld.itempool[i+1:]) + old_items.extend(multiworld.itempool[i+1:]) break else: - new_items.append(item) + old_items.append(item) # leftovers? if target: for player, remaining_items in depletion_pool.items(): remaining_items = {name: count for name, count in remaining_items.items() if count} if remaining_items: - raise Exception(f"{multiworld.get_player_name(player)}" + logger.warning(f"{multiworld.get_player_name(player)}" f" is trying to remove items from their pool that don't exist: {remaining_items}") - assert len(multiworld.itempool) == len(new_items), "Item Pool amounts should not change." - multiworld.itempool[:] = new_items + # find all filler we generated for the current player and remove until it matches + removables = [item for item in new_items if item.player == player] + for _ in range(sum(remaining_items.values())): + new_items.remove(removables.pop()) + assert len(multiworld.itempool) == len(new_items + old_items), "Item Pool amounts should not change." + multiworld.itempool[:] = new_items + old_items multiworld.link_items() @@ -341,7 +347,7 @@ def precollect_hint(location): output_file_futures.append(pool.submit(write_multidata)) if not check_accessibility_task.result(): if not multiworld.can_beat_game(): - raise Exception("Game appears as unbeatable. Aborting.") + raise FillError("Game appears as unbeatable. Aborting.", multiworld=multiworld) else: logger.warning("Location Accessibility requirements not fulfilled.") diff --git a/Options.py b/Options.py index d040828509d1..ecde6275f1ea 100644 --- a/Options.py +++ b/Options.py @@ -1236,6 +1236,7 @@ def as_dict(self, *option_names: str, casing: str = "snake") -> typing.Dict[str, :param option_names: names of the options to return :param casing: case of the keys to return. Supports `snake`, `camel`, `pascal`, `kebab` """ + assert option_names, "options.as_dict() was used without any option names." option_results = {} for option_name in option_names: if option_name in type(self).type_hints: @@ -1517,31 +1518,3 @@ def yaml_dump_scalar(scalar) -> str: with open(os.path.join(target_folder, game_name + ".yaml"), "w", encoding="utf-8-sig") as f: f.write(res) - - -if __name__ == "__main__": - - from worlds.alttp.Options import Logic - import argparse - - map_shuffle = Toggle - compass_shuffle = Toggle - key_shuffle = Toggle - big_key_shuffle = Toggle - hints = Toggle - test = argparse.Namespace() - test.logic = Logic.from_text("no_logic") - test.map_shuffle = map_shuffle.from_text("ON") - test.hints = hints.from_text('OFF') - try: - test.logic = Logic.from_text("overworld_glitches_typo") - except KeyError as e: - print(e) - try: - test.logic_owg = Logic.from_text("owg") - except KeyError as e: - print(e) - if test.map_shuffle: - print("map_shuffle is on") - print(f"Hints are {bool(test.hints)}") - print(test) diff --git a/test/bases.py b/test/bases.py index 5c2d241cbbfe..9fb223af2ac1 100644 --- a/test/bases.py +++ b/test/bases.py @@ -23,7 +23,7 @@ def get_state(self, items): state = CollectionState(self.multiworld) for item in items: item.classification = ItemClassification.progression - state.collect(item, event=True) + state.collect(item, prevent_sweep=True) state.sweep_for_events() state.update_reachable_regions(1) self._state_cache[self.multiworld, tuple(items)] = state diff --git a/test/multiworld/test_multiworlds.py b/test/multiworld/test_multiworlds.py index 5289cac6c357..8415ac4c8429 100644 --- a/test/multiworld/test_multiworlds.py +++ b/test/multiworld/test_multiworlds.py @@ -55,7 +55,7 @@ def test_fills(self) -> None: all_worlds = list(AutoWorldRegister.world_types.values()) self.multiworld = setup_multiworld(all_worlds, ()) for world in self.multiworld.worlds.values(): - world.options.accessibility.value = Accessibility.option_locations + world.options.accessibility.value = Accessibility.option_full self.assertSteps(gen_steps) with self.subTest("filling multiworld", seed=self.multiworld.seed): distribute_items_restrictive(self.multiworld) @@ -66,8 +66,8 @@ def test_fills(self) -> None: class TestTwoPlayerMulti(MultiworldTestBase): def test_two_player_single_game_fills(self) -> None: """Tests that a multiworld of two players for each registered game world can generate.""" - for world in AutoWorldRegister.world_types.values(): - self.multiworld = setup_multiworld([world, world], ()) + for world_type in AutoWorldRegister.world_types.values(): + self.multiworld = setup_multiworld([world_type, world_type], ()) for world in self.multiworld.worlds.values(): world.options.accessibility.value = Accessibility.option_full self.assertSteps(gen_steps) diff --git a/worlds/__init__.py b/worlds/__init__.py index bb2fe866d02d..c277ac9ca1de 100644 --- a/worlds/__init__.py +++ b/worlds/__init__.py @@ -73,7 +73,12 @@ def load(self) -> bool: else: # TODO: remove with 3.8 support mod = importer.load_module(os.path.basename(self.path).rsplit(".", 1)[0]) - mod.__package__ = f"worlds.{mod.__package__}" + if mod.__package__ is not None: + mod.__package__ = f"worlds.{mod.__package__}" + else: + # load_module does not populate package, we'll have to assume mod.__name__ is correct here + # probably safe to remove with 3.8 support + mod.__package__ = f"worlds.{mod.__name__}" mod.__name__ = f"worlds.{mod.__name__}" sys.modules[mod.__name__] = mod with warnings.catch_warnings(): diff --git a/worlds/alttp/test/dungeons/TestDungeon.py b/worlds/alttp/test/dungeons/TestDungeon.py index 91fc462c4ecc..796bfeec3f0e 100644 --- a/worlds/alttp/test/dungeons/TestDungeon.py +++ b/worlds/alttp/test/dungeons/TestDungeon.py @@ -54,7 +54,7 @@ def run_tests(self, access_pool): for item in items: item.classification = ItemClassification.progression - state.collect(item, event=True) # event=True prevents running sweep_for_events() and picking up + state.collect(item, prevent_sweep=True) # prevent_sweep=True prevents running sweep_for_events() and picking up state.sweep_for_events() # key drop keys repeatedly - self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}") \ No newline at end of file + self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}") diff --git a/worlds/clique/Items.py b/worlds/clique/Items.py index 5474f58b82d5..81e2540bacc0 100644 --- a/worlds/clique/Items.py +++ b/worlds/clique/Items.py @@ -1,6 +1,9 @@ -from typing import Callable, Dict, NamedTuple, Optional +from typing import Callable, Dict, NamedTuple, Optional, TYPE_CHECKING -from BaseClasses import Item, ItemClassification, MultiWorld +from BaseClasses import Item, ItemClassification + +if TYPE_CHECKING: + from . import CliqueWorld class CliqueItem(Item): @@ -10,7 +13,7 @@ class CliqueItem(Item): class CliqueItemData(NamedTuple): code: Optional[int] = None type: ItemClassification = ItemClassification.filler - can_create: Callable[[MultiWorld, int], bool] = lambda multiworld, player: True + can_create: Callable[["CliqueWorld"], bool] = lambda world: True item_data_table: Dict[str, CliqueItemData] = { @@ -21,11 +24,11 @@ class CliqueItemData(NamedTuple): "Button Activation": CliqueItemData( code=69696968, type=ItemClassification.progression, - can_create=lambda multiworld, player: bool(getattr(multiworld, "hard_mode")[player]), + can_create=lambda world: world.options.hard_mode, ), "A Cool Filler Item (No Satisfaction Guaranteed)": CliqueItemData( code=69696967, - can_create=lambda multiworld, player: False # Only created from `get_filler_item_name`. + can_create=lambda world: False # Only created from `get_filler_item_name`. ), "The Urge to Push": CliqueItemData( type=ItemClassification.progression, diff --git a/worlds/clique/Locations.py b/worlds/clique/Locations.py index 144becae5368..900b497eb4eb 100644 --- a/worlds/clique/Locations.py +++ b/worlds/clique/Locations.py @@ -1,6 +1,9 @@ -from typing import Callable, Dict, NamedTuple, Optional +from typing import Callable, Dict, NamedTuple, Optional, TYPE_CHECKING -from BaseClasses import Location, MultiWorld +from BaseClasses import Location + +if TYPE_CHECKING: + from . import CliqueWorld class CliqueLocation(Location): @@ -10,7 +13,7 @@ class CliqueLocation(Location): class CliqueLocationData(NamedTuple): region: str address: Optional[int] = None - can_create: Callable[[MultiWorld, int], bool] = lambda multiworld, player: True + can_create: Callable[["CliqueWorld"], bool] = lambda world: True locked_item: Optional[str] = None @@ -22,7 +25,7 @@ class CliqueLocationData(NamedTuple): "The Item on the Desk": CliqueLocationData( region="The Button Realm", address=69696968, - can_create=lambda multiworld, player: bool(getattr(multiworld, "hard_mode")[player]), + can_create=lambda world: world.options.hard_mode, ), "In the Player's Mind": CliqueLocationData( region="The Button Realm", diff --git a/worlds/clique/Options.py b/worlds/clique/Options.py index 7976dcb62130..d88a1289903c 100644 --- a/worlds/clique/Options.py +++ b/worlds/clique/Options.py @@ -1,6 +1,5 @@ -from typing import Dict - -from Options import Choice, Option, Toggle +from dataclasses import dataclass +from Options import Choice, Toggle, PerGameCommonOptions, StartInventoryPool class HardMode(Toggle): @@ -25,10 +24,11 @@ class ButtonColor(Choice): option_black = 11 -clique_options: Dict[str, type(Option)] = { - "color": ButtonColor, - "hard_mode": HardMode, +@dataclass +class CliqueOptions(PerGameCommonOptions): + color: ButtonColor + hard_mode: HardMode + start_inventory_from_pool: StartInventoryPool # DeathLink is always on. Always. - # "death_link": DeathLink, -} + # death_link: DeathLink diff --git a/worlds/clique/Rules.py b/worlds/clique/Rules.py index 5ae1d2c68e39..63ecd4e9e17c 100644 --- a/worlds/clique/Rules.py +++ b/worlds/clique/Rules.py @@ -1,10 +1,13 @@ -from typing import Callable +from typing import Callable, TYPE_CHECKING -from BaseClasses import CollectionState, MultiWorld +from BaseClasses import CollectionState +if TYPE_CHECKING: + from . import CliqueWorld -def get_button_rule(multiworld: MultiWorld, player: int) -> Callable[[CollectionState], bool]: - if getattr(multiworld, "hard_mode")[player]: - return lambda state: state.has("Button Activation", player) + +def get_button_rule(world: "CliqueWorld") -> Callable[[CollectionState], bool]: + if world.options.hard_mode: + return lambda state: state.has("Button Activation", world.player) return lambda state: True diff --git a/worlds/clique/__init__.py b/worlds/clique/__init__.py index b5cc74d94ac0..3d06e477eba7 100644 --- a/worlds/clique/__init__.py +++ b/worlds/clique/__init__.py @@ -1,10 +1,10 @@ -from typing import List +from typing import List, Dict, Any from BaseClasses import Region, Tutorial from worlds.AutoWorld import WebWorld, World from .Items import CliqueItem, item_data_table, item_table from .Locations import CliqueLocation, location_data_table, location_table, locked_locations -from .Options import clique_options +from .Options import CliqueOptions from .Regions import region_data_table from .Rules import get_button_rule @@ -38,7 +38,8 @@ class CliqueWorld(World): game = "Clique" web = CliqueWebWorld() - option_definitions = clique_options + options: CliqueOptions + options_dataclass = CliqueOptions location_name_to_id = location_table item_name_to_id = item_table @@ -48,7 +49,7 @@ def create_item(self, name: str) -> CliqueItem: def create_items(self) -> None: item_pool: List[CliqueItem] = [] for name, item in item_data_table.items(): - if item.code and item.can_create(self.multiworld, self.player): + if item.code and item.can_create(self): item_pool.append(self.create_item(name)) self.multiworld.itempool += item_pool @@ -61,41 +62,40 @@ def create_regions(self) -> None: # Create locations. for region_name, region_data in region_data_table.items(): - region = self.multiworld.get_region(region_name, self.player) + region = self.get_region(region_name) region.add_locations({ location_name: location_data.address for location_name, location_data in location_data_table.items() - if location_data.region == region_name and location_data.can_create(self.multiworld, self.player) + if location_data.region == region_name and location_data.can_create(self) }, CliqueLocation) region.add_exits(region_data_table[region_name].connecting_regions) # Place locked locations. for location_name, location_data in locked_locations.items(): # Ignore locations we never created. - if not location_data.can_create(self.multiworld, self.player): + if not location_data.can_create(self): continue locked_item = self.create_item(location_data_table[location_name].locked_item) - self.multiworld.get_location(location_name, self.player).place_locked_item(locked_item) + self.get_location(location_name).place_locked_item(locked_item) # Set priority location for the Big Red Button! - self.multiworld.priority_locations[self.player].value.add("The Big Red Button") + self.options.priority_locations.value.add("The Big Red Button") def get_filler_item_name(self) -> str: return "A Cool Filler Item (No Satisfaction Guaranteed)" def set_rules(self) -> None: - button_rule = get_button_rule(self.multiworld, self.player) - self.multiworld.get_location("The Big Red Button", self.player).access_rule = button_rule - self.multiworld.get_location("In the Player's Mind", self.player).access_rule = button_rule + button_rule = get_button_rule(self) + self.get_location("The Big Red Button").access_rule = button_rule + self.get_location("In the Player's Mind").access_rule = button_rule # Do not allow button activations on buttons. - self.multiworld.get_location("The Big Red Button", self.player).item_rule =\ - lambda item: item.name != "Button Activation" + self.get_location("The Big Red Button").item_rule = lambda item: item.name != "Button Activation" # Completion condition. self.multiworld.completion_condition[self.player] = lambda state: state.has("The Urge to Push", self.player) - def fill_slot_data(self): + def fill_slot_data(self) -> Dict[str, Any]: return { - "color": getattr(self.multiworld, "color")[self.player].current_key + "color": self.options.color.current_key } diff --git a/worlds/oot/EntranceShuffle.py b/worlds/oot/EntranceShuffle.py index bbdc30490c18..058fdbed0011 100644 --- a/worlds/oot/EntranceShuffle.py +++ b/worlds/oot/EntranceShuffle.py @@ -796,7 +796,7 @@ def validate_world(ootworld, entrance_placed, locations_to_ensure_reachable, all if ootworld.shuffle_interior_entrances or ootworld.shuffle_overworld_entrances or ootworld.spawn_positions: time_travel_state = none_state.copy() - time_travel_state.collect(ootworld.create_item('Time Travel'), event=True) + time_travel_state.collect(ootworld.create_item('Time Travel'), prevent_sweep=True) time_travel_state._oot_update_age_reachable_regions(player) # Unless entrances are decoupled, we don't want the player to end up through certain entrances as the wrong age diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index 89f10a5a2da0..24be303f822b 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -1388,7 +1388,7 @@ def get_state_with_complete_itempool(self): self.multiworld.worlds[item.player].collect(all_state, item) # If free_scarecrow give Scarecrow Song if self.free_scarecrow: - all_state.collect(self.create_item("Scarecrow Song"), event=True) + all_state.collect(self.create_item("Scarecrow Song"), prevent_sweep=True) all_state.stale[self.player] = True return all_state diff --git a/worlds/soe/__init__.py b/worlds/soe/__init__.py index 3baed165d821..161c749fd6bd 100644 --- a/worlds/soe/__init__.py +++ b/worlds/soe/__init__.py @@ -188,6 +188,7 @@ class SoEWorld(World): connect_name: str _halls_ne_chest_names: typing.List[str] = [loc.name for loc in _locations if 'Halls NE' in loc.name] + _fillers = sorted(item_name_groups["Ingredients"]) def __init__(self, multiworld: "MultiWorld", player: int): self.connect_name_available_event = threading.Event() @@ -469,7 +470,7 @@ def modify_multidata(self, multidata: typing.Dict[str, typing.Any]) -> None: multidata["connect_names"][self.connect_name] = payload def get_filler_item_name(self) -> str: - return self.random.choice(list(self.item_name_groups["Ingredients"])) + return self.random.choice(self._fillers) class SoEItem(Item): diff --git a/worlds/stardew_valley/test/TestCrops.py b/worlds/stardew_valley/test/TestCrops.py index 38b736367b80..362e6bf27e7c 100644 --- a/worlds/stardew_valley/test/TestCrops.py +++ b/worlds/stardew_valley/test/TestCrops.py @@ -11,10 +11,10 @@ def test_need_greenhouse_for_cactus(self): harvest_cactus = self.world.logic.region.can_reach_location("Harvest Cactus Fruit") self.assert_rule_false(harvest_cactus, self.multiworld.state) - self.multiworld.state.collect(self.world.create_item("Cactus Seeds"), event=False) - self.multiworld.state.collect(self.world.create_item("Shipping Bin"), event=False) - self.multiworld.state.collect(self.world.create_item("Desert Obelisk"), event=False) + self.multiworld.state.collect(self.world.create_item("Cactus Seeds"), prevent_sweep=False) + self.multiworld.state.collect(self.world.create_item("Shipping Bin"), prevent_sweep=False) + self.multiworld.state.collect(self.world.create_item("Desert Obelisk"), prevent_sweep=False) self.assert_rule_false(harvest_cactus, self.multiworld.state) - self.multiworld.state.collect(self.world.create_item("Greenhouse"), event=False) + self.multiworld.state.collect(self.world.create_item("Greenhouse"), prevent_sweep=False) self.assert_rule_true(harvest_cactus, self.multiworld.state) diff --git a/worlds/stardew_valley/test/TestDynamicGoals.py b/worlds/stardew_valley/test/TestDynamicGoals.py index fe1bfb5f3044..bfa58dd34063 100644 --- a/worlds/stardew_valley/test/TestDynamicGoals.py +++ b/worlds/stardew_valley/test/TestDynamicGoals.py @@ -12,29 +12,29 @@ def collect_fishing_abilities(tester: SVTestBase): for i in range(4): - tester.multiworld.state.collect(tester.world.create_item(APTool.fishing_rod), event=False) - tester.multiworld.state.collect(tester.world.create_item(APTool.pickaxe), event=False) - tester.multiworld.state.collect(tester.world.create_item(APTool.axe), event=False) - tester.multiworld.state.collect(tester.world.create_item(APWeapon.weapon), event=False) + tester.multiworld.state.collect(tester.world.create_item(APTool.fishing_rod), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item(APTool.pickaxe), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item(APTool.axe), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item(APWeapon.weapon), prevent_sweep=False) for i in range(10): - tester.multiworld.state.collect(tester.world.create_item("Fishing Level"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Combat Level"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Mining Level"), event=False) + tester.multiworld.state.collect(tester.world.create_item("Fishing Level"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Combat Level"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Mining Level"), prevent_sweep=False) for i in range(17): - tester.multiworld.state.collect(tester.world.create_item("Progressive Mine Elevator"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Spring"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Summer"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Fall"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Winter"), event=False) - tester.multiworld.state.collect(tester.world.create_item(Transportation.desert_obelisk), event=False) - tester.multiworld.state.collect(tester.world.create_item("Railroad Boulder Removed"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Island North Turtle"), event=False) - tester.multiworld.state.collect(tester.world.create_item("Island West Turtle"), event=False) + tester.multiworld.state.collect(tester.world.create_item("Progressive Mine Elevator"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Spring"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Summer"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Fall"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Winter"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item(Transportation.desert_obelisk), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Railroad Boulder Removed"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Island North Turtle"), prevent_sweep=False) + tester.multiworld.state.collect(tester.world.create_item("Island West Turtle"), prevent_sweep=False) def create_and_collect(tester: SVTestBase, item_name: str) -> StardewItem: item = tester.world.create_item(item_name) - tester.multiworld.state.collect(item, event=False) + tester.multiworld.state.collect(item, prevent_sweep=False) return item diff --git a/worlds/stardew_valley/test/TestLogic.py b/worlds/stardew_valley/test/TestLogic.py index 65f7352a5e36..da00a0f43e43 100644 --- a/worlds/stardew_valley/test/TestLogic.py +++ b/worlds/stardew_valley/test/TestLogic.py @@ -12,7 +12,7 @@ def collect_all(mw): for item in mw.get_items(): - mw.state.collect(item, event=True) + mw.state.collect(item, prevent_sweep=True) class LogicTestBase(RuleAssertMixin, TestCase): diff --git a/worlds/stardew_valley/test/__init__.py b/worlds/stardew_valley/test/__init__.py index 7e82ea91e434..c2c2a6a20baf 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -257,16 +257,16 @@ def run_default_tests(self) -> bool: return super().run_default_tests def collect_lots_of_money(self): - self.multiworld.state.collect(self.world.create_item("Shipping Bin"), event=False) + self.multiworld.state.collect(self.world.create_item("Shipping Bin"), prevent_sweep=False) required_prog_items = int(round(self.multiworld.worlds[self.player].total_progression_items * 0.25)) for i in range(required_prog_items): - self.multiworld.state.collect(self.world.create_item("Stardrop"), event=False) + self.multiworld.state.collect(self.world.create_item("Stardrop"), prevent_sweep=False) def collect_all_the_money(self): - self.multiworld.state.collect(self.world.create_item("Shipping Bin"), event=False) + self.multiworld.state.collect(self.world.create_item("Shipping Bin"), prevent_sweep=False) required_prog_items = int(round(self.multiworld.worlds[self.player].total_progression_items * 0.95)) for i in range(required_prog_items): - self.multiworld.state.collect(self.world.create_item("Stardrop"), event=False) + self.multiworld.state.collect(self.world.create_item("Stardrop"), prevent_sweep=False) def collect_everything(self): non_event_items = [item for item in self.multiworld.get_items() if item.code] diff --git a/worlds/stardew_valley/test/assertion/world_assert.py b/worlds/stardew_valley/test/assertion/world_assert.py index c1c24bdf75b4..97172834543c 100644 --- a/worlds/stardew_valley/test/assertion/world_assert.py +++ b/worlds/stardew_valley/test/assertion/world_assert.py @@ -33,14 +33,14 @@ def assert_item_was_necessary_for_victory(self, item: StardewItem, multiworld: M self.assert_can_reach_victory(multiworld) multiworld.state.remove(item) self.assert_cannot_reach_victory(multiworld) - multiworld.state.collect(item, event=False) + multiworld.state.collect(item, prevent_sweep=False) self.assert_can_reach_victory(multiworld) def assert_item_was_not_necessary_for_victory(self, item: StardewItem, multiworld: MultiWorld): self.assert_can_reach_victory(multiworld) multiworld.state.remove(item) self.assert_can_reach_victory(multiworld) - multiworld.state.collect(item, event=False) + multiworld.state.collect(item, prevent_sweep=False) self.assert_can_reach_victory(multiworld) def assert_can_win(self, multiworld: MultiWorld): diff --git a/worlds/stardew_valley/test/rules/TestArcades.py b/worlds/stardew_valley/test/rules/TestArcades.py index fb62a456378a..2922ecfb5d9e 100644 --- a/worlds/stardew_valley/test/rules/TestArcades.py +++ b/worlds/stardew_valley/test/rules/TestArcades.py @@ -19,8 +19,8 @@ def test_prairie_king(self): life = self.create_item("JotPK: Extra Life") drop = self.create_item("JotPK: Increased Drop Rate") - self.multiworld.state.collect(boots, event=True) - self.multiworld.state.collect(gun, event=True) + self.multiworld.state.collect(boots, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) @@ -28,8 +28,8 @@ def test_prairie_king(self): self.remove(boots) self.remove(gun) - self.multiworld.state.collect(boots, event=True) - self.multiworld.state.collect(boots, event=True) + self.multiworld.state.collect(boots, prevent_sweep=True) + self.multiworld.state.collect(boots, prevent_sweep=True) self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) self.assertFalse(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) @@ -37,10 +37,10 @@ def test_prairie_king(self): self.remove(boots) self.remove(boots) - self.multiworld.state.collect(boots, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(ammo, event=True) - self.multiworld.state.collect(life, event=True) + self.multiworld.state.collect(boots, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(ammo, prevent_sweep=True) + self.multiworld.state.collect(life, prevent_sweep=True) self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) self.assertFalse(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) @@ -50,13 +50,13 @@ def test_prairie_king(self): self.remove(ammo) self.remove(life) - self.multiworld.state.collect(boots, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(ammo, event=True) - self.multiworld.state.collect(ammo, event=True) - self.multiworld.state.collect(life, event=True) - self.multiworld.state.collect(drop, event=True) + self.multiworld.state.collect(boots, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(ammo, prevent_sweep=True) + self.multiworld.state.collect(ammo, prevent_sweep=True) + self.multiworld.state.collect(life, prevent_sweep=True) + self.multiworld.state.collect(drop, prevent_sweep=True) self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) self.assertTrue(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) @@ -69,17 +69,17 @@ def test_prairie_king(self): self.remove(life) self.remove(drop) - self.multiworld.state.collect(boots, event=True) - self.multiworld.state.collect(boots, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(gun, event=True) - self.multiworld.state.collect(ammo, event=True) - self.multiworld.state.collect(ammo, event=True) - self.multiworld.state.collect(ammo, event=True) - self.multiworld.state.collect(life, event=True) - self.multiworld.state.collect(drop, event=True) + self.multiworld.state.collect(boots, prevent_sweep=True) + self.multiworld.state.collect(boots, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(gun, prevent_sweep=True) + self.multiworld.state.collect(ammo, prevent_sweep=True) + self.multiworld.state.collect(ammo, prevent_sweep=True) + self.multiworld.state.collect(ammo, prevent_sweep=True) + self.multiworld.state.collect(life, prevent_sweep=True) + self.multiworld.state.collect(drop, prevent_sweep=True) self.assertTrue(self.world.logic.region.can_reach("JotPK World 1")(self.multiworld.state)) self.assertTrue(self.world.logic.region.can_reach("JotPK World 2")(self.multiworld.state)) self.assertTrue(self.world.logic.region.can_reach("JotPK World 3")(self.multiworld.state)) diff --git a/worlds/stardew_valley/test/rules/TestBuildings.py b/worlds/stardew_valley/test/rules/TestBuildings.py index b00e4138a195..2c276d8b5cbe 100644 --- a/worlds/stardew_valley/test/rules/TestBuildings.py +++ b/worlds/stardew_valley/test/rules/TestBuildings.py @@ -23,11 +23,11 @@ def test_big_coop_blueprint(self): self.assertFalse(big_coop_blueprint_rule(self.multiworld.state), f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}") - self.multiworld.state.collect(self.create_item("Can Construct Buildings"), event=True) + self.multiworld.state.collect(self.create_item("Can Construct Buildings"), prevent_sweep=True) self.assertFalse(big_coop_blueprint_rule(self.multiworld.state), f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}") - self.multiworld.state.collect(self.create_item("Progressive Coop"), event=False) + self.multiworld.state.collect(self.create_item("Progressive Coop"), prevent_sweep=False) self.assertTrue(big_coop_blueprint_rule(self.multiworld.state), f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}") @@ -35,13 +35,13 @@ def test_deluxe_coop_blueprint(self): self.assertFalse(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) self.collect_lots_of_money() - self.multiworld.state.collect(self.create_item("Can Construct Buildings"), event=True) + self.multiworld.state.collect(self.create_item("Can Construct Buildings"), prevent_sweep=True) self.assertFalse(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) - self.multiworld.state.collect(self.create_item("Progressive Coop"), event=True) + self.multiworld.state.collect(self.create_item("Progressive Coop"), prevent_sweep=True) self.assertFalse(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) - self.multiworld.state.collect(self.create_item("Progressive Coop"), event=True) + self.multiworld.state.collect(self.create_item("Progressive Coop"), prevent_sweep=True) self.assertTrue(self.world.logic.region.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) def test_big_shed_blueprint(self): @@ -53,10 +53,10 @@ def test_big_shed_blueprint(self): self.assertFalse(big_shed_rule(self.multiworld.state), f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}") - self.multiworld.state.collect(self.create_item("Can Construct Buildings"), event=True) + self.multiworld.state.collect(self.create_item("Can Construct Buildings"), prevent_sweep=True) self.assertFalse(big_shed_rule(self.multiworld.state), f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}") - self.multiworld.state.collect(self.create_item("Progressive Shed"), event=True) + self.multiworld.state.collect(self.create_item("Progressive Shed"), prevent_sweep=True) self.assertTrue(big_shed_rule(self.multiworld.state), f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}") diff --git a/worlds/stardew_valley/test/rules/TestCookingRecipes.py b/worlds/stardew_valley/test/rules/TestCookingRecipes.py index 81a91d1e7482..7ab9d61cb942 100644 --- a/worlds/stardew_valley/test/rules/TestCookingRecipes.py +++ b/worlds/stardew_valley/test/rules/TestCookingRecipes.py @@ -17,14 +17,14 @@ def test_can_learn_qos_recipe(self): rule = self.world.logic.region.can_reach_location(location) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Progressive House"), event=False) - self.multiworld.state.collect(self.create_item("Radish Seeds"), event=False) - self.multiworld.state.collect(self.create_item("Spring"), event=False) - self.multiworld.state.collect(self.create_item("Summer"), event=False) + self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Radish Seeds"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Spring"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Summer"), prevent_sweep=False) self.collect_lots_of_money() self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("The Queen of Sauce"), event=False) + self.multiworld.state.collect(self.create_item("The Queen of Sauce"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) @@ -42,21 +42,21 @@ def test_can_learn_qos_recipe(self): rule = self.world.logic.region.can_reach_location(location) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Progressive House"), event=False) - self.multiworld.state.collect(self.create_item("Radish Seeds"), event=False) - self.multiworld.state.collect(self.create_item("Summer"), event=False) + self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Radish Seeds"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Summer"), prevent_sweep=False) self.collect_lots_of_money() self.assert_rule_false(rule, self.multiworld.state) spring = self.create_item("Spring") qos = self.create_item("The Queen of Sauce") - self.multiworld.state.collect(spring, event=False) - self.multiworld.state.collect(qos, event=False) + self.multiworld.state.collect(spring, prevent_sweep=False) + self.multiworld.state.collect(qos, prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) self.multiworld.state.remove(spring) self.multiworld.state.remove(qos) - self.multiworld.state.collect(self.create_item("Radish Salad Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Radish Salad Recipe"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) def test_get_chefsanity_check_recipe(self): @@ -64,20 +64,20 @@ def test_get_chefsanity_check_recipe(self): rule = self.world.logic.region.can_reach_location(location) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Spring"), event=False) + self.multiworld.state.collect(self.create_item("Spring"), prevent_sweep=False) self.collect_lots_of_money() self.assert_rule_false(rule, self.multiworld.state) seeds = self.create_item("Radish Seeds") summer = self.create_item("Summer") house = self.create_item("Progressive House") - self.multiworld.state.collect(seeds, event=False) - self.multiworld.state.collect(summer, event=False) - self.multiworld.state.collect(house, event=False) + self.multiworld.state.collect(seeds, prevent_sweep=False) + self.multiworld.state.collect(summer, prevent_sweep=False) + self.multiworld.state.collect(house, prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) self.multiworld.state.remove(seeds) self.multiworld.state.remove(summer) self.multiworld.state.remove(house) - self.multiworld.state.collect(self.create_item("The Queen of Sauce"), event=False) + self.multiworld.state.collect(self.create_item("The Queen of Sauce"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) diff --git a/worlds/stardew_valley/test/rules/TestCraftingRecipes.py b/worlds/stardew_valley/test/rules/TestCraftingRecipes.py index 59d41f6a63d6..93c325ae5c5c 100644 --- a/worlds/stardew_valley/test/rules/TestCraftingRecipes.py +++ b/worlds/stardew_valley/test/rules/TestCraftingRecipes.py @@ -25,7 +25,7 @@ def test_can_craft_recipe(self): self.collect_all_the_money() self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Marble Brazier Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Marble Brazier Recipe"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) def test_can_learn_crafting_recipe(self): @@ -38,16 +38,16 @@ def test_can_learn_crafting_recipe(self): def test_can_craft_festival_recipe(self): recipe = all_crafting_recipes_by_name["Jack-O-Lantern"] - self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False) - self.multiworld.state.collect(self.create_item("Torch Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Torch Recipe"), prevent_sweep=False) self.collect_lots_of_money() rule = self.world.logic.crafting.can_craft(recipe) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Fall"), event=False) + self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) @@ -62,16 +62,16 @@ class TestCraftsanityWithFestivalsLogic(SVTestBase): def test_can_craft_festival_recipe(self): recipe = all_crafting_recipes_by_name["Jack-O-Lantern"] - self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False) - self.multiworld.state.collect(self.create_item("Fall"), event=False) + self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False) self.collect_lots_of_money() rule = self.world.logic.crafting.can_craft(recipe) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Torch Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Torch Recipe"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) @@ -92,7 +92,7 @@ def test_can_craft_recipe(self): def test_can_craft_festival_recipe(self): recipe = all_crafting_recipes_by_name["Jack-O-Lantern"] - self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False) + self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False) self.collect_lots_of_money() rule = self.world.logic.crafting.can_craft(recipe) result = rule(self.multiworld.state) @@ -113,11 +113,11 @@ class TestNoCraftsanityWithFestivalsLogic(SVTestBase): def test_can_craft_festival_recipe(self): recipe = all_crafting_recipes_by_name["Jack-O-Lantern"] - self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), event=False) - self.multiworld.state.collect(self.create_item("Fall"), event=False) + self.multiworld.state.collect(self.create_item("Pumpkin Seeds"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False) self.collect_lots_of_money() rule = self.world.logic.crafting.can_craft(recipe) self.assert_rule_false(rule, self.multiworld.state) - self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), event=False) + self.multiworld.state.collect(self.create_item("Jack-O-Lantern Recipe"), prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) diff --git a/worlds/stardew_valley/test/rules/TestDonations.py b/worlds/stardew_valley/test/rules/TestDonations.py index 84ceac50ff5a..984a3ebc38b4 100644 --- a/worlds/stardew_valley/test/rules/TestDonations.py +++ b/worlds/stardew_valley/test/rules/TestDonations.py @@ -18,7 +18,7 @@ def test_cannot_make_any_donation_without_museum_access(self): for donation in locations_by_tag[LocationTags.MUSEUM_DONATIONS]: self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) - self.multiworld.state.collect(self.create_item(railroad_item), event=False) + self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False) for donation in locations_by_tag[LocationTags.MUSEUM_DONATIONS]: self.assertTrue(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) @@ -39,7 +39,7 @@ def test_cannot_make_any_donation_without_museum_access(self): for donation in donation_locations: self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) - self.multiworld.state.collect(self.create_item(railroad_item), event=False) + self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False) for donation in donation_locations: self.assertTrue(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) @@ -58,7 +58,7 @@ def test_cannot_make_any_donation_without_museum_access(self): for donation in locations_by_tag[LocationTags.MUSEUM_MILESTONES]: self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) - self.multiworld.state.collect(self.create_item(railroad_item), event=False) + self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False) for donation in locations_by_tag[LocationTags.MUSEUM_MILESTONES]: self.assertTrue(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) diff --git a/worlds/stardew_valley/test/rules/TestFriendship.py b/worlds/stardew_valley/test/rules/TestFriendship.py index 43c5e55c7fca..fb186ca99480 100644 --- a/worlds/stardew_valley/test/rules/TestFriendship.py +++ b/worlds/stardew_valley/test/rules/TestFriendship.py @@ -11,34 +11,34 @@ class TestFriendsanityDatingRules(SVTestBase): def test_earning_dating_heart_requires_dating(self): self.collect_all_the_money() - self.multiworld.state.collect(self.create_item("Fall"), event=False) - self.multiworld.state.collect(self.create_item("Beach Bridge"), event=False) - self.multiworld.state.collect(self.create_item("Progressive House"), event=False) + self.multiworld.state.collect(self.create_item("Fall"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Beach Bridge"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=False) for i in range(3): - self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=False) - self.multiworld.state.collect(self.create_item("Progressive Weapon"), event=False) - self.multiworld.state.collect(self.create_item("Progressive Axe"), event=False) - self.multiworld.state.collect(self.create_item("Progressive Barn"), event=False) + self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive Weapon"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive Axe"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive Barn"), prevent_sweep=False) for i in range(10): - self.multiworld.state.collect(self.create_item("Foraging Level"), event=False) - self.multiworld.state.collect(self.create_item("Farming Level"), event=False) - self.multiworld.state.collect(self.create_item("Mining Level"), event=False) - self.multiworld.state.collect(self.create_item("Combat Level"), event=False) - self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), event=False) - self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), event=False) + self.multiworld.state.collect(self.create_item("Foraging Level"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Farming Level"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Mining Level"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Combat Level"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive Mine Elevator"), prevent_sweep=False) npc = "Abigail" heart_name = f"{npc} <3" step = 3 self.assert_can_reach_heart_up_to(npc, 3, step) - self.multiworld.state.collect(self.create_item(heart_name), event=False) + self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False) self.assert_can_reach_heart_up_to(npc, 6, step) - self.multiworld.state.collect(self.create_item(heart_name), event=False) + self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False) self.assert_can_reach_heart_up_to(npc, 8, step) - self.multiworld.state.collect(self.create_item(heart_name), event=False) + self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False) self.assert_can_reach_heart_up_to(npc, 10, step) - self.multiworld.state.collect(self.create_item(heart_name), event=False) + self.multiworld.state.collect(self.create_item(heart_name), prevent_sweep=False) self.assert_can_reach_heart_up_to(npc, 14, step) def assert_can_reach_heart_up_to(self, npc: str, max_reachable: int, step: int): diff --git a/worlds/stardew_valley/test/rules/TestShipping.py b/worlds/stardew_valley/test/rules/TestShipping.py index 378933b7d75d..973d8d3ada7d 100644 --- a/worlds/stardew_valley/test/rules/TestShipping.py +++ b/worlds/stardew_valley/test/rules/TestShipping.py @@ -76,7 +76,7 @@ def test_all_shipsanity_locations_require_shipping_bin(self): with self.subTest(location.name): self.remove(bin_item) self.assertFalse(self.world.logic.region.can_reach_location(location.name)(self.multiworld.state)) - self.multiworld.state.collect(bin_item, event=False) + self.multiworld.state.collect(bin_item, prevent_sweep=False) shipsanity_rule = self.world.logic.region.can_reach_location(location.name) self.assert_rule_true(shipsanity_rule, self.multiworld.state) self.remove(bin_item) diff --git a/worlds/stardew_valley/test/rules/TestTools.py b/worlds/stardew_valley/test/rules/TestTools.py index a1fb152812c8..5f0fe8ef3ffb 100644 --- a/worlds/stardew_valley/test/rules/TestTools.py +++ b/worlds/stardew_valley/test/rules/TestTools.py @@ -21,30 +21,30 @@ def test_sturgeon(self): self.assert_rule_false(sturgeon_rule, self.multiworld.state) summer = self.create_item("Summer") - self.multiworld.state.collect(summer, event=False) + self.multiworld.state.collect(summer, prevent_sweep=False) self.assert_rule_false(sturgeon_rule, self.multiworld.state) fishing_rod = self.create_item("Progressive Fishing Rod") - self.multiworld.state.collect(fishing_rod, event=False) - self.multiworld.state.collect(fishing_rod, event=False) + self.multiworld.state.collect(fishing_rod, prevent_sweep=False) + self.multiworld.state.collect(fishing_rod, prevent_sweep=False) self.assert_rule_false(sturgeon_rule, self.multiworld.state) fishing_level = self.create_item("Fishing Level") - self.multiworld.state.collect(fishing_level, event=False) + self.multiworld.state.collect(fishing_level, prevent_sweep=False) self.assert_rule_false(sturgeon_rule, self.multiworld.state) - self.multiworld.state.collect(fishing_level, event=False) - self.multiworld.state.collect(fishing_level, event=False) - self.multiworld.state.collect(fishing_level, event=False) - self.multiworld.state.collect(fishing_level, event=False) - self.multiworld.state.collect(fishing_level, event=False) + self.multiworld.state.collect(fishing_level, prevent_sweep=False) + self.multiworld.state.collect(fishing_level, prevent_sweep=False) + self.multiworld.state.collect(fishing_level, prevent_sweep=False) + self.multiworld.state.collect(fishing_level, prevent_sweep=False) + self.multiworld.state.collect(fishing_level, prevent_sweep=False) self.assert_rule_true(sturgeon_rule, self.multiworld.state) self.remove(summer) self.assert_rule_false(sturgeon_rule, self.multiworld.state) winter = self.create_item("Winter") - self.multiworld.state.collect(winter, event=False) + self.multiworld.state.collect(winter, prevent_sweep=False) self.assert_rule_true(sturgeon_rule, self.multiworld.state) self.remove(fishing_rod) @@ -53,24 +53,24 @@ def test_sturgeon(self): def test_old_master_cannoli(self): self.multiworld.state.prog_items = {1: Counter()} - self.multiworld.state.collect(self.create_item("Progressive Axe"), event=False) - self.multiworld.state.collect(self.create_item("Progressive Axe"), event=False) - self.multiworld.state.collect(self.create_item("Summer"), event=False) + self.multiworld.state.collect(self.create_item("Progressive Axe"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Progressive Axe"), prevent_sweep=False) + self.multiworld.state.collect(self.create_item("Summer"), prevent_sweep=False) self.collect_lots_of_money() rule = self.world.logic.region.can_reach_location("Old Master Cannoli") self.assert_rule_false(rule, self.multiworld.state) fall = self.create_item("Fall") - self.multiworld.state.collect(fall, event=False) + self.multiworld.state.collect(fall, prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) tuesday = self.create_item("Traveling Merchant: Tuesday") - self.multiworld.state.collect(tuesday, event=False) + self.multiworld.state.collect(tuesday, prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) rare_seed = self.create_item("Rare Seed") - self.multiworld.state.collect(rare_seed, event=False) + self.multiworld.state.collect(rare_seed, prevent_sweep=False) self.assert_rule_true(rule, self.multiworld.state) self.remove(fall) @@ -80,11 +80,11 @@ def test_old_master_cannoli(self): green_house = self.create_item("Greenhouse") self.collect(self.create_item(Event.fall_farming)) - self.multiworld.state.collect(green_house, event=False) + self.multiworld.state.collect(green_house, prevent_sweep=False) self.assert_rule_false(rule, self.multiworld.state) friday = self.create_item("Traveling Merchant: Friday") - self.multiworld.state.collect(friday, event=False) + self.multiworld.state.collect(friday, prevent_sweep=False) self.assertTrue(self.multiworld.get_location("Old Master Cannoli", 1).access_rule(self.multiworld.state)) self.remove(green_house) @@ -111,7 +111,7 @@ def test_cannot_get_any_tool_without_blacksmith_access(self): for material in [ToolMaterial.copper, ToolMaterial.iron, ToolMaterial.gold, ToolMaterial.iridium]: self.assert_rule_false(self.world.logic.tool.has_tool(tool, material), self.multiworld.state) - self.multiworld.state.collect(self.create_item(railroad_item), event=False) + self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False) for tool in [Tool.pickaxe, Tool.axe, Tool.hoe, Tool.trash_can, Tool.watering_can]: for material in [ToolMaterial.copper, ToolMaterial.iron, ToolMaterial.gold, ToolMaterial.iridium]: @@ -125,7 +125,7 @@ def test_cannot_get_fishing_rod_without_willy_access(self): for fishing_rod_level in [3, 4]: self.assert_rule_false(self.world.logic.tool.has_fishing_rod(fishing_rod_level), self.multiworld.state) - self.multiworld.state.collect(self.create_item(railroad_item), event=False) + self.multiworld.state.collect(self.create_item(railroad_item), prevent_sweep=False) for fishing_rod_level in [3, 4]: self.assert_rule_true(self.world.logic.tool.has_fishing_rod(fishing_rod_level), self.multiworld.state) diff --git a/worlds/stardew_valley/test/rules/TestWeapons.py b/worlds/stardew_valley/test/rules/TestWeapons.py index 77887f8eca0c..972170b93c75 100644 --- a/worlds/stardew_valley/test/rules/TestWeapons.py +++ b/worlds/stardew_valley/test/rules/TestWeapons.py @@ -10,16 +10,16 @@ class TestWeaponsLogic(SVTestBase): } def test_mine(self): - self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True) - self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True) - self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True) - self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), event=True) - self.multiworld.state.collect(self.create_item("Progressive House"), event=True) + self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True) + self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True) + self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True) + self.multiworld.state.collect(self.create_item("Progressive Pickaxe"), prevent_sweep=True) + self.multiworld.state.collect(self.create_item("Progressive House"), prevent_sweep=True) self.collect([self.create_item("Combat Level")] * 10) self.collect([self.create_item("Mining Level")] * 10) self.collect([self.create_item("Progressive Mine Elevator")] * 24) - self.multiworld.state.collect(self.create_item("Bus Repair"), event=True) - self.multiworld.state.collect(self.create_item("Skull Key"), event=True) + self.multiworld.state.collect(self.create_item("Bus Repair"), prevent_sweep=True) + self.multiworld.state.collect(self.create_item("Skull Key"), prevent_sweep=True) self.GiveItemAndCheckReachableMine("Progressive Sword", 1) self.GiveItemAndCheckReachableMine("Progressive Dagger", 1) @@ -43,7 +43,7 @@ def test_mine(self): def GiveItemAndCheckReachableMine(self, item_name: str, reachable_level: int): item = self.multiworld.create_item(item_name, self.player) - self.multiworld.state.collect(item, event=True) + self.multiworld.state.collect(item, prevent_sweep=True) rule = self.world.logic.mine.can_mine_in_the_mines_floor_1_40() if reachable_level > 0: self.assert_rule_true(rule, self.multiworld.state) diff --git a/worlds/timespinner/Locations.py b/worlds/timespinner/Locations.py index 86839f0f2167..f99dd7615571 100644 --- a/worlds/timespinner/Locations.py +++ b/worlds/timespinner/Locations.py @@ -135,11 +135,11 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio LocationData('Upper Lake Serene', 'Lake Serene: Pyramid keys room', 1337104), LocationData('Upper Lake Serene', 'Lake Serene (Upper): Chicken ledge', 1337174), LocationData('Lower Lake Serene', 'Lake Serene (Lower): Deep dive', 1337105), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): Under the eels', 1337106), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Under the eels', 1337106, lambda state: state.has('Water Mask', player)), LocationData('Lower Lake Serene', 'Lake Serene (Lower): Water spikes room', 1337107), LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater secret', 1337108, logic.can_break_walls), LocationData('Lower Lake Serene', 'Lake Serene (Lower): T chest', 1337109, lambda state: flooded.flood_lake_serene or logic.has_doublejump_of_npc(state)), - LocationData('Lower Lake Serene', 'Lake Serene (Lower): Past the eels', 1337110), + LocationData('Left Side forest Caves', 'Lake Serene (Lower): Past the eels', 1337110, lambda state: state.has('Water Mask', player)), LocationData('Lower Lake Serene', 'Lake Serene (Lower): Underwater pedestal', 1337111, lambda state: flooded.flood_lake_serene or logic.has_doublejump(state)), LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Shroom jump room', 1337112, lambda state: flooded.flood_maw or logic.has_doublejump(state)), LocationData('Caves of Banishment (upper)', 'Caves of Banishment (Maw): Secret room', 1337113, lambda state: logic.can_break_walls(state) and (not flooded.flood_maw or state.has('Water Mask', player))), diff --git a/worlds/tloz/__init__.py b/worlds/tloz/__init__.py index 8ea5f3e18ca1..c8c76bd85a8a 100644 --- a/worlds/tloz/__init__.py +++ b/worlds/tloz/__init__.py @@ -110,8 +110,8 @@ class TLoZWorld(World): if v is not None: location_name_to_id[k] = v + base_id - def __init__(self, world: MultiWorld, player: int): - super().__init__(world, player) + def __init__(self, multiworld: MultiWorld, player: int): + super().__init__(multiworld, player) self.generator_in_use = threading.Event() self.rom_name_available_event = threading.Event() self.levels = None diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 5253e9951437..47c66591f912 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -155,8 +155,7 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: if is_mismatched: raise Exception(f"TUNIC: Conflict between seed group {group}'s plando " f"connection {group_cxn.entrance} <-> {group_cxn.exit} and " - f"{tunic.multiworld.get_player_name(tunic.player)}'s plando " - f"connection {cxn.entrance} <-> {cxn.exit}") + f"{tunic.player_name}'s plando connection {cxn.entrance} <-> {cxn.exit}") if new_cxn: cls.seed_groups[group]["plando"].value.append(cxn) @@ -187,17 +186,17 @@ def create_items(self) -> None: if self.options.laurels_location: laurels = self.create_item("Hero's Laurels") if self.options.laurels_location == "6_coins": - self.multiworld.get_location("Coins in the Well - 6 Coins", self.player).place_locked_item(laurels) + self.get_location("Coins in the Well - 6 Coins").place_locked_item(laurels) elif self.options.laurels_location == "10_coins": - self.multiworld.get_location("Coins in the Well - 10 Coins", self.player).place_locked_item(laurels) + self.get_location("Coins in the Well - 10 Coins").place_locked_item(laurels) elif self.options.laurels_location == "10_fairies": - self.multiworld.get_location("Secret Gathering Place - 10 Fairy Reward", self.player).place_locked_item(laurels) + self.get_location("Secret Gathering Place - 10 Fairy Reward").place_locked_item(laurels) items_to_create["Hero's Laurels"] = 0 if self.options.keys_behind_bosses: for rgb_hexagon, location in hexagon_locations.items(): hex_item = self.create_item(gold_hexagon if self.options.hexagon_quest else rgb_hexagon) - self.multiworld.get_location(location, self.player).place_locked_item(hex_item) + self.get_location(location).place_locked_item(hex_item) items_to_create[rgb_hexagon] = 0 items_to_create[gold_hexagon] -= 3 @@ -297,15 +296,15 @@ def create_regions(self) -> None: self.multiworld.regions.append(region) for region_name, exits in tunic_regions.items(): - region = self.multiworld.get_region(region_name, self.player) + region = self.get_region(region_name) region.add_exits(exits) for location_name, location_id in self.location_name_to_id.items(): - region = self.multiworld.get_region(location_table[location_name].region, self.player) + region = self.get_region(location_table[location_name].region) location = TunicLocation(self.player, location_name, location_id, region) region.locations.append(location) - victory_region = self.multiworld.get_region("Spirit Arena", self.player) + victory_region = self.get_region("Spirit Arena") victory_location = TunicLocation(self.player, "The Heir", None, victory_region) victory_location.place_locked_item(TunicItem("Victory", ItemClassification.progression, None, self.player)) self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) @@ -339,10 +338,8 @@ def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None: name, connection = paths[location.parent_region] except KeyError: # logic bug, proceed with warning since it takes a long time to update AP - warning(f"{location.name} is not logically accessible for " - f"{self.multiworld.get_file_safe_player_name(self.player)}. " - "Creating entrance hint Inaccessible. " - "Please report this to the TUNIC rando devs.") + warning(f"{location.name} is not logically accessible for {self.player_name}. " + "Creating entrance hint Inaccessible. Please report this to the TUNIC rando devs.") hint_text = "Inaccessible" else: while connection != ("Menu", None): @@ -410,7 +407,9 @@ def fill_slot_data(self) -> Dict[str, Any]: return slot_data # for the universal tracker, doesn't get called in standard gen + # docs: https://github.com/FarisTheAncient/Archipelago/blob/tracker/worlds/tracker/docs/re-gen-passthrough.md @staticmethod def interpret_slot_data(slot_data: Dict[str, Any]) -> Dict[str, Any]: # returning slot_data so it regens, giving it back in multiworld.re_gen_passthrough + # we are using re_gen_passthrough over modifying the world here due to complexities with ER return slot_data diff --git a/worlds/tunic/er_rules.py b/worlds/tunic/er_rules.py index 81e9d48b4afc..a54ea23bcc0a 100644 --- a/worlds/tunic/er_rules.py +++ b/worlds/tunic/er_rules.py @@ -1318,222 +1318,221 @@ def get_portal_info(portal_sd: str) -> Tuple[str, str]: def set_er_location_rules(world: "TunicWorld") -> None: player = world.player - multiworld = world.multiworld options = world.options - forbid_item(multiworld.get_location("Secret Gathering Place - 20 Fairy Reward", player), fairies, player) + forbid_item(world.get_location("Secret Gathering Place - 20 Fairy Reward"), fairies, player) # Ability Shuffle Exclusive Rules - set_rule(multiworld.get_location("East Forest - Dancing Fox Spirit Holy Cross", player), + set_rule(world.get_location("East Forest - Dancing Fox Spirit Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Forest Grave Path - Holy Cross Code by Grave", player), + set_rule(world.get_location("Forest Grave Path - Holy Cross Code by Grave"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("East Forest - Golden Obelisk Holy Cross", player), + set_rule(world.get_location("East Forest - Golden Obelisk Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Beneath the Well - [Powered Secret Room] Chest", player), + set_rule(world.get_location("Beneath the Well - [Powered Secret Room] Chest"), lambda state: state.has("Activate Furnace Fuse", player)) - set_rule(multiworld.get_location("West Garden - [North] Behind Holy Cross Door", player), + set_rule(world.get_location("West Garden - [North] Behind Holy Cross Door"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Library Hall - Holy Cross Chest", player), + set_rule(world.get_location("Library Hall - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Eastern Vault Fortress - [West Wing] Candles Holy Cross", player), + set_rule(world.get_location("Eastern Vault Fortress - [West Wing] Candles Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("West Garden - [Central Highlands] Holy Cross (Blue Lines)", player), + set_rule(world.get_location("West Garden - [Central Highlands] Holy Cross (Blue Lines)"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Quarry - [Back Entrance] Bushes Holy Cross", player), + set_rule(world.get_location("Quarry - [Back Entrance] Bushes Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Cathedral - Secret Legend Trophy Chest", player), + set_rule(world.get_location("Cathedral - Secret Legend Trophy Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Overworld - [Southwest] Flowers Holy Cross", player), + set_rule(world.get_location("Overworld - [Southwest] Flowers Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Overworld - [East] Weathervane Holy Cross", player), + set_rule(world.get_location("Overworld - [East] Weathervane Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Overworld - [Northeast] Flowers Holy Cross", player), + set_rule(world.get_location("Overworld - [Northeast] Flowers Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Overworld - [Southwest] Haiku Holy Cross", player), + set_rule(world.get_location("Overworld - [Southwest] Haiku Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Overworld - [Northwest] Golden Obelisk Page", player), + set_rule(world.get_location("Overworld - [Northwest] Golden Obelisk Page"), lambda state: has_ability(holy_cross, state, world)) # Overworld - set_rule(multiworld.get_location("Overworld - [Southwest] Grapple Chest Over Walkway", player), + set_rule(world.get_location("Overworld - [Southwest] Grapple Chest Over Walkway"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2", player), + set_rule(world.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Overworld - [Southwest] From West Garden", player), + set_rule(world.get_location("Overworld - [Southwest] From West Garden"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Overworld - [Southeast] Page on Pillar by Swamp", player), + set_rule(world.get_location("Overworld - [Southeast] Page on Pillar by Swamp"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Overworld - [Southwest] Fountain Page", player), + set_rule(world.get_location("Overworld - [Southwest] Fountain Page"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Overworld - [Northwest] Page on Pillar by Dark Tomb", player), + set_rule(world.get_location("Overworld - [Northwest] Page on Pillar by Dark Tomb"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Old House - Holy Cross Chest", player), + set_rule(world.get_location("Old House - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Overworld - [East] Grapple Chest", player), + set_rule(world.get_location("Overworld - [East] Grapple Chest"), lambda state: state.has(grapple, player)) - set_rule(multiworld.get_location("Sealed Temple - Holy Cross Chest", player), + set_rule(world.get_location("Sealed Temple - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Caustic Light Cave - Holy Cross Chest", player), + set_rule(world.get_location("Caustic Light Cave - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Cube Cave - Holy Cross Chest", player), + set_rule(world.get_location("Cube Cave - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Old House - Holy Cross Door Page", player), + set_rule(world.get_location("Old House - Holy Cross Door Page"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Maze Cave - Maze Room Holy Cross", player), + set_rule(world.get_location("Maze Cave - Maze Room Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Old House - Holy Cross Chest", player), + set_rule(world.get_location("Old House - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Patrol Cave - Holy Cross Chest", player), + set_rule(world.get_location("Patrol Cave - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Ruined Passage - Holy Cross Chest", player), + set_rule(world.get_location("Ruined Passage - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Hourglass Cave - Holy Cross Chest", player), + set_rule(world.get_location("Hourglass Cave - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Secret Gathering Place - Holy Cross Chest", player), + set_rule(world.get_location("Secret Gathering Place - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Secret Gathering Place - 10 Fairy Reward", player), + set_rule(world.get_location("Secret Gathering Place - 10 Fairy Reward"), lambda state: state.has(fairies, player, 10)) - set_rule(multiworld.get_location("Secret Gathering Place - 20 Fairy Reward", player), + set_rule(world.get_location("Secret Gathering Place - 20 Fairy Reward"), lambda state: state.has(fairies, player, 20)) - set_rule(multiworld.get_location("Coins in the Well - 3 Coins", player), + set_rule(world.get_location("Coins in the Well - 3 Coins"), lambda state: state.has(coins, player, 3)) - set_rule(multiworld.get_location("Coins in the Well - 6 Coins", player), + set_rule(world.get_location("Coins in the Well - 6 Coins"), lambda state: state.has(coins, player, 6)) - set_rule(multiworld.get_location("Coins in the Well - 10 Coins", player), + set_rule(world.get_location("Coins in the Well - 10 Coins"), lambda state: state.has(coins, player, 10)) - set_rule(multiworld.get_location("Coins in the Well - 15 Coins", player), + set_rule(world.get_location("Coins in the Well - 15 Coins"), lambda state: state.has(coins, player, 15)) # East Forest - set_rule(multiworld.get_location("East Forest - Lower Grapple Chest", player), + set_rule(world.get_location("East Forest - Lower Grapple Chest"), lambda state: state.has(grapple, player)) - set_rule(multiworld.get_location("East Forest - Lower Dash Chest", player), + set_rule(world.get_location("East Forest - Lower Dash Chest"), lambda state: state.has_all({grapple, laurels}, player)) - set_rule(multiworld.get_location("East Forest - Ice Rod Grapple Chest", player), lambda state: ( + set_rule(world.get_location("East Forest - Ice Rod Grapple Chest"), lambda state: ( state.has_all({grapple, ice_dagger, fire_wand}, player) and has_ability(icebolt, state, world))) # West Garden - set_rule(multiworld.get_location("West Garden - [North] Across From Page Pickup", player), + set_rule(world.get_location("West Garden - [North] Across From Page Pickup"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("West Garden - [West] In Flooded Walkway", player), + set_rule(world.get_location("West Garden - [West] In Flooded Walkway"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("West Garden - [West Lowlands] Tree Holy Cross Chest", player), + set_rule(world.get_location("West Garden - [West Lowlands] Tree Holy Cross Chest"), lambda state: state.has(laurels, player) and has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("West Garden - [East Lowlands] Page Behind Ice Dagger House", player), + set_rule(world.get_location("West Garden - [East Lowlands] Page Behind Ice Dagger House"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("West Garden - [Central Lowlands] Below Left Walkway", player), + set_rule(world.get_location("West Garden - [Central Lowlands] Below Left Walkway"), lambda state: state.has(laurels, player)) # Ruined Atoll - set_rule(multiworld.get_location("Ruined Atoll - [West] Near Kevin Block", player), + set_rule(world.get_location("Ruined Atoll - [West] Near Kevin Block"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Ruined Atoll - [East] Locked Room Lower Chest", player), + set_rule(world.get_location("Ruined Atoll - [East] Locked Room Lower Chest"), lambda state: state.has(laurels, player) or state.has(key, player, 2)) - set_rule(multiworld.get_location("Ruined Atoll - [East] Locked Room Upper Chest", player), + set_rule(world.get_location("Ruined Atoll - [East] Locked Room Upper Chest"), lambda state: state.has(laurels, player) or state.has(key, player, 2)) # Frog's Domain - set_rule(multiworld.get_location("Frog's Domain - Side Room Grapple Secret", player), + set_rule(world.get_location("Frog's Domain - Side Room Grapple Secret"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Frog's Domain - Grapple Above Hot Tub", player), + set_rule(world.get_location("Frog's Domain - Grapple Above Hot Tub"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Frog's Domain - Escape Chest", player), + set_rule(world.get_location("Frog's Domain - Escape Chest"), lambda state: state.has_any({grapple, laurels}, player)) # Eastern Vault Fortress - set_rule(multiworld.get_location("Fortress Arena - Hexagon Red", player), + set_rule(world.get_location("Fortress Arena - Hexagon Red"), lambda state: state.has(vault_key, player)) # Beneath the Vault - set_rule(multiworld.get_location("Beneath the Fortress - Bridge", player), + set_rule(world.get_location("Beneath the Fortress - Bridge"), lambda state: state.has_group("Melee Weapons", player, 1) or state.has_any({laurels, fire_wand}, player)) # Quarry - set_rule(multiworld.get_location("Quarry - [Central] Above Ladder Dash Chest", player), + set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"), lambda state: state.has(laurels, player)) # Ziggurat # if ER is off, you still need to get past the Admin or you'll get stuck in lower zig - set_rule(multiworld.get_location("Rooted Ziggurat Upper - Near Bridge Switch", player), + set_rule(world.get_location("Rooted Ziggurat Upper - Near Bridge Switch"), lambda state: has_sword(state, player) or (state.has(fire_wand, player) and (state.has(laurels, player) or options.entrance_rando))) - set_rule(multiworld.get_location("Rooted Ziggurat Lower - After Guarded Fuse", player), + set_rule(world.get_location("Rooted Ziggurat Lower - After Guarded Fuse"), lambda state: has_sword(state, player) and has_ability(prayer, state, world)) # Bosses - set_rule(multiworld.get_location("Fortress Arena - Siege Engine/Vault Key Pickup", player), + set_rule(world.get_location("Fortress Arena - Siege Engine/Vault Key Pickup"), lambda state: has_sword(state, player)) # nmg - kill Librarian with a lure, or gun I guess - set_rule(multiworld.get_location("Librarian - Hexagon Green", player), + set_rule(world.get_location("Librarian - Hexagon Green"), lambda state: (has_sword(state, player) or options.logic_rules) and has_ladder("Ladders in Library", state, world)) # nmg - kill boss scav with orb + firecracker, or similar - set_rule(multiworld.get_location("Rooted Ziggurat Lower - Hexagon Blue", player), + set_rule(world.get_location("Rooted Ziggurat Lower - Hexagon Blue"), lambda state: has_sword(state, player) or (state.has(grapple, player) and options.logic_rules)) # Swamp - set_rule(multiworld.get_location("Cathedral Gauntlet - Gauntlet Reward", player), + set_rule(world.get_location("Cathedral Gauntlet - Gauntlet Reward"), lambda state: state.has(fire_wand, player) and has_sword(state, player)) - set_rule(multiworld.get_location("Swamp - [Entrance] Above Entryway", player), + set_rule(world.get_location("Swamp - [Entrance] Above Entryway"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Swamp - [South Graveyard] Upper Walkway Dash Chest", player), + set_rule(world.get_location("Swamp - [South Graveyard] Upper Walkway Dash Chest"), lambda state: state.has(laurels, player)) # these two swamp checks really want you to kill the big skeleton first - set_rule(multiworld.get_location("Swamp - [South Graveyard] 4 Orange Skulls", player), + set_rule(world.get_location("Swamp - [South Graveyard] 4 Orange Skulls"), lambda state: has_sword(state, player)) # Hero's Grave and Far Shore - set_rule(multiworld.get_location("Hero's Grave - Tooth Relic", player), + set_rule(world.get_location("Hero's Grave - Tooth Relic"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Hero's Grave - Mushroom Relic", player), + set_rule(world.get_location("Hero's Grave - Mushroom Relic"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Hero's Grave - Ash Relic", player), + set_rule(world.get_location("Hero's Grave - Ash Relic"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Hero's Grave - Flowers Relic", player), + set_rule(world.get_location("Hero's Grave - Flowers Relic"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Hero's Grave - Effigy Relic", player), + set_rule(world.get_location("Hero's Grave - Effigy Relic"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Hero's Grave - Feathers Relic", player), + set_rule(world.get_location("Hero's Grave - Feathers Relic"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Far Shore - Secret Chest", player), + set_rule(world.get_location("Far Shore - Secret Chest"), lambda state: state.has(laurels, player)) # Events - set_rule(multiworld.get_location("Eastern Bell", player), + set_rule(world.get_location("Eastern Bell"), lambda state: (has_stick(state, player) or state.has(fire_wand, player))) - set_rule(multiworld.get_location("Western Bell", player), + set_rule(world.get_location("Western Bell"), lambda state: (has_stick(state, player) or state.has(fire_wand, player))) - set_rule(multiworld.get_location("Furnace Fuse", player), + set_rule(world.get_location("Furnace Fuse"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("South and West Fortress Exterior Fuses", player), + set_rule(world.get_location("South and West Fortress Exterior Fuses"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Upper and Central Fortress Exterior Fuses", player), + set_rule(world.get_location("Upper and Central Fortress Exterior Fuses"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Beneath the Vault Fuse", player), + set_rule(world.get_location("Beneath the Vault Fuse"), lambda state: state.has("Activate South and West Fortress Exterior Fuses", player)) - set_rule(multiworld.get_location("Eastern Vault West Fuses", player), + set_rule(world.get_location("Eastern Vault West Fuses"), lambda state: state.has("Activate Beneath the Vault Fuse", player)) - set_rule(multiworld.get_location("Eastern Vault East Fuse", player), + set_rule(world.get_location("Eastern Vault East Fuse"), lambda state: state.has_all({"Activate Upper and Central Fortress Exterior Fuses", "Activate South and West Fortress Exterior Fuses"}, player)) - set_rule(multiworld.get_location("Quarry Connector Fuse", player), + set_rule(world.get_location("Quarry Connector Fuse"), lambda state: has_ability(prayer, state, world) and state.has(grapple, player)) - set_rule(multiworld.get_location("Quarry Fuse", player), + set_rule(world.get_location("Quarry Fuse"), lambda state: state.has("Activate Quarry Connector Fuse", player)) - set_rule(multiworld.get_location("Ziggurat Fuse", player), + set_rule(world.get_location("Ziggurat Fuse"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("West Garden Fuse", player), + set_rule(world.get_location("West Garden Fuse"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Library Fuse", player), + set_rule(world.get_location("Library Fuse"), lambda state: has_ability(prayer, state, world)) # Shop - set_rule(multiworld.get_location("Shop - Potion 1", player), + set_rule(world.get_location("Shop - Potion 1"), lambda state: has_sword(state, player)) - set_rule(multiworld.get_location("Shop - Potion 2", player), + set_rule(world.get_location("Shop - Potion 2"), lambda state: has_sword(state, player)) - set_rule(multiworld.get_location("Shop - Coin 1", player), + set_rule(world.get_location("Shop - Coin 1"), lambda state: has_sword(state, player)) - set_rule(multiworld.get_location("Shop - Coin 2", player), + set_rule(world.get_location("Shop - Coin 2"), lambda state: has_sword(state, player)) diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index a4295cf9f2a4..e7c8fd58d0c6 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -130,7 +130,7 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]: portal_pairs: Dict[Portal, Portal] = {} dead_ends: List[Portal] = [] two_plus: List[Portal] = [] - player_name = world.multiworld.get_player_name(world.player) + player_name = world.player_name portal_map = portal_mapping.copy() logic_rules = world.options.logic_rules.value fixed_shop = world.options.fixed_shop diff --git a/worlds/tunic/rules.py b/worlds/tunic/rules.py index 73eb8118901b..2ff588da904d 100644 --- a/worlds/tunic/rules.py +++ b/worlds/tunic/rules.py @@ -87,41 +87,40 @@ def has_lantern(state: CollectionState, world: "TunicWorld") -> bool: def set_region_rules(world: "TunicWorld") -> None: - multiworld = world.multiworld player = world.player options = world.options - multiworld.get_entrance("Overworld -> Overworld Holy Cross", player).access_rule = \ + world.get_entrance("Overworld -> Overworld Holy Cross").access_rule = \ lambda state: has_ability(holy_cross, state, world) - multiworld.get_entrance("Overworld -> Beneath the Well", player).access_rule = \ + world.get_entrance("Overworld -> Beneath the Well").access_rule = \ lambda state: has_stick(state, player) or state.has(fire_wand, player) - multiworld.get_entrance("Overworld -> Dark Tomb", player).access_rule = \ + world.get_entrance("Overworld -> Dark Tomb").access_rule = \ lambda state: has_lantern(state, world) - multiworld.get_entrance("Overworld -> West Garden", player).access_rule = \ + world.get_entrance("Overworld -> West Garden").access_rule = \ lambda state: state.has(laurels, player) \ or can_ladder_storage(state, world) - multiworld.get_entrance("Overworld -> Eastern Vault Fortress", player).access_rule = \ + world.get_entrance("Overworld -> Eastern Vault Fortress").access_rule = \ lambda state: state.has(laurels, player) \ or has_ice_grapple_logic(True, state, world) \ or can_ladder_storage(state, world) # using laurels or ls to get in is covered by the -> Eastern Vault Fortress rules - multiworld.get_entrance("Overworld -> Beneath the Vault", player).access_rule = \ + world.get_entrance("Overworld -> Beneath the Vault").access_rule = \ lambda state: has_lantern(state, world) and has_ability(prayer, state, world) - multiworld.get_entrance("Ruined Atoll -> Library", player).access_rule = \ + world.get_entrance("Ruined Atoll -> Library").access_rule = \ lambda state: state.has_any({grapple, laurels}, player) and has_ability(prayer, state, world) - multiworld.get_entrance("Overworld -> Quarry", player).access_rule = \ + world.get_entrance("Overworld -> Quarry").access_rule = \ lambda state: (has_sword(state, player) or state.has(fire_wand, player)) \ and (state.has_any({grapple, laurels}, player) or can_ladder_storage(state, world)) - multiworld.get_entrance("Quarry Back -> Quarry", player).access_rule = \ + world.get_entrance("Quarry Back -> Quarry").access_rule = \ lambda state: has_sword(state, player) or state.has(fire_wand, player) - multiworld.get_entrance("Quarry -> Lower Quarry", player).access_rule = \ + world.get_entrance("Quarry -> Lower Quarry").access_rule = \ lambda state: has_mask(state, world) - multiworld.get_entrance("Lower Quarry -> Rooted Ziggurat", player).access_rule = \ + world.get_entrance("Lower Quarry -> Rooted Ziggurat").access_rule = \ lambda state: state.has(grapple, player) and has_ability(prayer, state, world) - multiworld.get_entrance("Swamp -> Cathedral", player).access_rule = \ + world.get_entrance("Swamp -> Cathedral").access_rule = \ lambda state: state.has(laurels, player) and has_ability(prayer, state, world) \ or has_ice_grapple_logic(False, state, world) - multiworld.get_entrance("Overworld -> Spirit Arena", player).access_rule = \ + world.get_entrance("Overworld -> Spirit Arena").access_rule = \ lambda state: ((state.has(gold_hexagon, player, options.hexagon_goal.value) if options.hexagon_quest.value else state.has_all({red_hexagon, green_hexagon, blue_hexagon}, player) and state.has_group_unique("Hero Relics", player, 6)) @@ -130,210 +129,209 @@ def set_region_rules(world: "TunicWorld") -> None: def set_location_rules(world: "TunicWorld") -> None: - multiworld = world.multiworld player = world.player options = world.options - forbid_item(multiworld.get_location("Secret Gathering Place - 20 Fairy Reward", player), fairies, player) + forbid_item(world.get_location("Secret Gathering Place - 20 Fairy Reward"), fairies, player) # Ability Shuffle Exclusive Rules - set_rule(multiworld.get_location("Far Shore - Page Pickup", player), + set_rule(world.get_location("Far Shore - Page Pickup"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Fortress Courtyard - Chest Near Cave", player), + set_rule(world.get_location("Fortress Courtyard - Chest Near Cave"), lambda state: has_ability(prayer, state, world) or state.has(laurels, player) or can_ladder_storage(state, world) or (has_ice_grapple_logic(True, state, world) and has_lantern(state, world))) - set_rule(multiworld.get_location("Fortress Courtyard - Page Near Cave", player), + set_rule(world.get_location("Fortress Courtyard - Page Near Cave"), lambda state: has_ability(prayer, state, world) or state.has(laurels, player) or can_ladder_storage(state, world) or (has_ice_grapple_logic(True, state, world) and has_lantern(state, world))) - set_rule(multiworld.get_location("East Forest - Dancing Fox Spirit Holy Cross", player), + set_rule(world.get_location("East Forest - Dancing Fox Spirit Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Forest Grave Path - Holy Cross Code by Grave", player), + set_rule(world.get_location("Forest Grave Path - Holy Cross Code by Grave"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("East Forest - Golden Obelisk Holy Cross", player), + set_rule(world.get_location("East Forest - Golden Obelisk Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Beneath the Well - [Powered Secret Room] Chest", player), + set_rule(world.get_location("Beneath the Well - [Powered Secret Room] Chest"), lambda state: has_ability(prayer, state, world)) - set_rule(multiworld.get_location("West Garden - [North] Behind Holy Cross Door", player), + set_rule(world.get_location("West Garden - [North] Behind Holy Cross Door"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Library Hall - Holy Cross Chest", player), + set_rule(world.get_location("Library Hall - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Eastern Vault Fortress - [West Wing] Candles Holy Cross", player), + set_rule(world.get_location("Eastern Vault Fortress - [West Wing] Candles Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("West Garden - [Central Highlands] Holy Cross (Blue Lines)", player), + set_rule(world.get_location("West Garden - [Central Highlands] Holy Cross (Blue Lines)"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Quarry - [Back Entrance] Bushes Holy Cross", player), + set_rule(world.get_location("Quarry - [Back Entrance] Bushes Holy Cross"), lambda state: has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("Cathedral - Secret Legend Trophy Chest", player), + set_rule(world.get_location("Cathedral - Secret Legend Trophy Chest"), lambda state: has_ability(holy_cross, state, world)) # Overworld - set_rule(multiworld.get_location("Overworld - [Southwest] Fountain Page", player), + set_rule(world.get_location("Overworld - [Southwest] Fountain Page"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Overworld - [Southwest] Grapple Chest Over Walkway", player), + set_rule(world.get_location("Overworld - [Southwest] Grapple Chest Over Walkway"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2", player), + set_rule(world.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Far Shore - Secret Chest", player), + set_rule(world.get_location("Far Shore - Secret Chest"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Overworld - [Southeast] Page on Pillar by Swamp", player), + set_rule(world.get_location("Overworld - [Southeast] Page on Pillar by Swamp"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Old House - Normal Chest", player), + set_rule(world.get_location("Old House - Normal Chest"), lambda state: state.has(house_key, player) or has_ice_grapple_logic(False, state, world) or (state.has(laurels, player) and options.logic_rules)) - set_rule(multiworld.get_location("Old House - Holy Cross Chest", player), + set_rule(world.get_location("Old House - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world) and ( state.has(house_key, player) or has_ice_grapple_logic(False, state, world) or (state.has(laurels, player) and options.logic_rules))) - set_rule(multiworld.get_location("Old House - Shield Pickup", player), + set_rule(world.get_location("Old House - Shield Pickup"), lambda state: state.has(house_key, player) or has_ice_grapple_logic(False, state, world) or (state.has(laurels, player) and options.logic_rules)) - set_rule(multiworld.get_location("Overworld - [Northwest] Page on Pillar by Dark Tomb", player), + set_rule(world.get_location("Overworld - [Northwest] Page on Pillar by Dark Tomb"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Overworld - [Southwest] From West Garden", player), + set_rule(world.get_location("Overworld - [Southwest] From West Garden"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Overworld - [West] Chest After Bell", player), + set_rule(world.get_location("Overworld - [West] Chest After Bell"), lambda state: state.has(laurels, player) or (has_lantern(state, world) and has_sword(state, player)) or can_ladder_storage(state, world)) - set_rule(multiworld.get_location("Overworld - [Northwest] Chest Beneath Quarry Gate", player), + set_rule(world.get_location("Overworld - [Northwest] Chest Beneath Quarry Gate"), lambda state: state.has_any({grapple, laurels}, player) or options.logic_rules) - set_rule(multiworld.get_location("Overworld - [East] Grapple Chest", player), + set_rule(world.get_location("Overworld - [East] Grapple Chest"), lambda state: state.has(grapple, player)) - set_rule(multiworld.get_location("Special Shop - Secret Page Pickup", player), + set_rule(world.get_location("Special Shop - Secret Page Pickup"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Sealed Temple - Holy Cross Chest", player), + set_rule(world.get_location("Sealed Temple - Holy Cross Chest"), lambda state: has_ability(holy_cross, state, world) and (state.has(laurels, player) or (has_lantern(state, world) and (has_sword(state, player) or state.has(fire_wand, player))) or has_ice_grapple_logic(False, state, world))) - set_rule(multiworld.get_location("Sealed Temple - Page Pickup", player), + set_rule(world.get_location("Sealed Temple - Page Pickup"), lambda state: state.has(laurels, player) or (has_lantern(state, world) and (has_sword(state, player) or state.has(fire_wand, player))) or has_ice_grapple_logic(False, state, world)) - set_rule(multiworld.get_location("West Furnace - Lantern Pickup", player), + set_rule(world.get_location("West Furnace - Lantern Pickup"), lambda state: has_stick(state, player) or state.has_any({fire_wand, laurels}, player)) - set_rule(multiworld.get_location("Secret Gathering Place - 10 Fairy Reward", player), + set_rule(world.get_location("Secret Gathering Place - 10 Fairy Reward"), lambda state: state.has(fairies, player, 10)) - set_rule(multiworld.get_location("Secret Gathering Place - 20 Fairy Reward", player), + set_rule(world.get_location("Secret Gathering Place - 20 Fairy Reward"), lambda state: state.has(fairies, player, 20)) - set_rule(multiworld.get_location("Coins in the Well - 3 Coins", player), + set_rule(world.get_location("Coins in the Well - 3 Coins"), lambda state: state.has(coins, player, 3)) - set_rule(multiworld.get_location("Coins in the Well - 6 Coins", player), + set_rule(world.get_location("Coins in the Well - 6 Coins"), lambda state: state.has(coins, player, 6)) - set_rule(multiworld.get_location("Coins in the Well - 10 Coins", player), + set_rule(world.get_location("Coins in the Well - 10 Coins"), lambda state: state.has(coins, player, 10)) - set_rule(multiworld.get_location("Coins in the Well - 15 Coins", player), + set_rule(world.get_location("Coins in the Well - 15 Coins"), lambda state: state.has(coins, player, 15)) # East Forest - set_rule(multiworld.get_location("East Forest - Lower Grapple Chest", player), + set_rule(world.get_location("East Forest - Lower Grapple Chest"), lambda state: state.has(grapple, player)) - set_rule(multiworld.get_location("East Forest - Lower Dash Chest", player), + set_rule(world.get_location("East Forest - Lower Dash Chest"), lambda state: state.has_all({grapple, laurels}, player)) - set_rule(multiworld.get_location("East Forest - Ice Rod Grapple Chest", player), + set_rule(world.get_location("East Forest - Ice Rod Grapple Chest"), lambda state: state.has_all({grapple, ice_dagger, fire_wand}, player) and has_ability(icebolt, state, world)) # West Garden - set_rule(multiworld.get_location("West Garden - [North] Across From Page Pickup", player), + set_rule(world.get_location("West Garden - [North] Across From Page Pickup"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("West Garden - [West] In Flooded Walkway", player), + set_rule(world.get_location("West Garden - [West] In Flooded Walkway"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("West Garden - [West Lowlands] Tree Holy Cross Chest", player), + set_rule(world.get_location("West Garden - [West Lowlands] Tree Holy Cross Chest"), lambda state: state.has(laurels, player) and has_ability(holy_cross, state, world)) - set_rule(multiworld.get_location("West Garden - [East Lowlands] Page Behind Ice Dagger House", player), + set_rule(world.get_location("West Garden - [East Lowlands] Page Behind Ice Dagger House"), lambda state: (state.has(laurels, player) and has_ability(prayer, state, world)) or has_ice_grapple_logic(True, state, world)) - set_rule(multiworld.get_location("West Garden - [Central Lowlands] Below Left Walkway", player), + set_rule(world.get_location("West Garden - [Central Lowlands] Below Left Walkway"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("West Garden - [Central Highlands] After Garden Knight", player), + set_rule(world.get_location("West Garden - [Central Highlands] After Garden Knight"), lambda state: state.has(laurels, player) or (has_lantern(state, world) and has_sword(state, player)) or can_ladder_storage(state, world)) # Ruined Atoll - set_rule(multiworld.get_location("Ruined Atoll - [West] Near Kevin Block", player), + set_rule(world.get_location("Ruined Atoll - [West] Near Kevin Block"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Ruined Atoll - [East] Locked Room Lower Chest", player), + set_rule(world.get_location("Ruined Atoll - [East] Locked Room Lower Chest"), lambda state: state.has(laurels, player) or state.has(key, player, 2)) - set_rule(multiworld.get_location("Ruined Atoll - [East] Locked Room Upper Chest", player), + set_rule(world.get_location("Ruined Atoll - [East] Locked Room Upper Chest"), lambda state: state.has(laurels, player) or state.has(key, player, 2)) - set_rule(multiworld.get_location("Librarian - Hexagon Green", player), + set_rule(world.get_location("Librarian - Hexagon Green"), lambda state: has_sword(state, player) or options.logic_rules) # Frog's Domain - set_rule(multiworld.get_location("Frog's Domain - Side Room Grapple Secret", player), + set_rule(world.get_location("Frog's Domain - Side Room Grapple Secret"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Frog's Domain - Grapple Above Hot Tub", player), + set_rule(world.get_location("Frog's Domain - Grapple Above Hot Tub"), lambda state: state.has_any({grapple, laurels}, player)) - set_rule(multiworld.get_location("Frog's Domain - Escape Chest", player), + set_rule(world.get_location("Frog's Domain - Escape Chest"), lambda state: state.has_any({grapple, laurels}, player)) # Eastern Vault Fortress - set_rule(multiworld.get_location("Fortress Leaf Piles - Secret Chest", player), + set_rule(world.get_location("Fortress Leaf Piles - Secret Chest"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Fortress Arena - Siege Engine/Vault Key Pickup", player), + set_rule(world.get_location("Fortress Arena - Siege Engine/Vault Key Pickup"), lambda state: has_sword(state, player) and (has_ability(prayer, state, world) or has_ice_grapple_logic(False, state, world))) - set_rule(multiworld.get_location("Fortress Arena - Hexagon Red", player), + set_rule(world.get_location("Fortress Arena - Hexagon Red"), lambda state: state.has(vault_key, player) and (has_ability(prayer, state, world) or has_ice_grapple_logic(False, state, world))) # Beneath the Vault - set_rule(multiworld.get_location("Beneath the Fortress - Bridge", player), + set_rule(world.get_location("Beneath the Fortress - Bridge"), lambda state: has_stick(state, player) or state.has_any({laurels, fire_wand}, player)) - set_rule(multiworld.get_location("Beneath the Fortress - Obscured Behind Waterfall", player), + set_rule(world.get_location("Beneath the Fortress - Obscured Behind Waterfall"), lambda state: has_stick(state, player) and has_lantern(state, world)) # Quarry - set_rule(multiworld.get_location("Quarry - [Central] Above Ladder Dash Chest", player), + set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Rooted Ziggurat Upper - Near Bridge Switch", player), + set_rule(world.get_location("Rooted Ziggurat Upper - Near Bridge Switch"), lambda state: has_sword(state, player) or state.has_all({fire_wand, laurels}, player)) # nmg - kill boss scav with orb + firecracker, or similar - set_rule(multiworld.get_location("Rooted Ziggurat Lower - Hexagon Blue", player), + set_rule(world.get_location("Rooted Ziggurat Lower - Hexagon Blue"), lambda state: has_sword(state, player) or (state.has(grapple, player) and options.logic_rules)) # Swamp - set_rule(multiworld.get_location("Cathedral Gauntlet - Gauntlet Reward", player), + set_rule(world.get_location("Cathedral Gauntlet - Gauntlet Reward"), lambda state: (state.has(fire_wand, player) and has_sword(state, player)) and (state.has(laurels, player) or has_ice_grapple_logic(False, state, world))) - set_rule(multiworld.get_location("Swamp - [Entrance] Above Entryway", player), + set_rule(world.get_location("Swamp - [Entrance] Above Entryway"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Swamp - [South Graveyard] Upper Walkway Dash Chest", player), + set_rule(world.get_location("Swamp - [South Graveyard] Upper Walkway Dash Chest"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Swamp - [Outside Cathedral] Obscured Behind Memorial", player), + set_rule(world.get_location("Swamp - [Outside Cathedral] Obscured Behind Memorial"), lambda state: state.has(laurels, player)) - set_rule(multiworld.get_location("Swamp - [South Graveyard] 4 Orange Skulls", player), + set_rule(world.get_location("Swamp - [South Graveyard] 4 Orange Skulls"), lambda state: has_sword(state, player)) # Hero's Grave - set_rule(multiworld.get_location("Hero's Grave - Tooth Relic", player), + set_rule(world.get_location("Hero's Grave - Tooth Relic"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Hero's Grave - Mushroom Relic", player), + set_rule(world.get_location("Hero's Grave - Mushroom Relic"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Hero's Grave - Ash Relic", player), + set_rule(world.get_location("Hero's Grave - Ash Relic"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Hero's Grave - Flowers Relic", player), + set_rule(world.get_location("Hero's Grave - Flowers Relic"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Hero's Grave - Effigy Relic", player), + set_rule(world.get_location("Hero's Grave - Effigy Relic"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) - set_rule(multiworld.get_location("Hero's Grave - Feathers Relic", player), + set_rule(world.get_location("Hero's Grave - Feathers Relic"), lambda state: state.has(laurels, player) and has_ability(prayer, state, world)) # Shop - set_rule(multiworld.get_location("Shop - Potion 1", player), + set_rule(world.get_location("Shop - Potion 1"), lambda state: has_sword(state, player)) - set_rule(multiworld.get_location("Shop - Potion 2", player), + set_rule(world.get_location("Shop - Potion 2"), lambda state: has_sword(state, player)) - set_rule(multiworld.get_location("Shop - Coin 1", player), + set_rule(world.get_location("Shop - Coin 1"), lambda state: has_sword(state, player)) - set_rule(multiworld.get_location("Shop - Coin 2", player), + set_rule(world.get_location("Shop - Coin 2"), lambda state: has_sword(state, player)) diff --git a/worlds/undertale/__init__.py b/worlds/undertale/__init__.py index 9084c77b0065..9f09bb34526b 100644 --- a/worlds/undertale/__init__.py +++ b/worlds/undertale/__init__.py @@ -67,12 +67,15 @@ def _get_undertale_data(self): "only_flakes": bool(self.options.only_flakes.value), "no_equips": bool(self.options.no_equips.value), "key_hunt": bool(self.options.key_hunt.value), - "key_pieces": self.options.key_pieces.value, - "rando_love": bool(self.options.rando_love.value), - "rando_stats": bool(self.options.rando_stats.value), + "key_pieces": int(self.options.key_pieces.value), + "rando_love": bool(self.options.rando_love and (self.options.route_required == "genocide" or self.options.route_required == "all_routes")), + "rando_stats": bool(self.options.rando_stats and (self.options.route_required == "genocide" or self.options.route_required == "all_routes")), "prog_armor": bool(self.options.prog_armor.value), "prog_weapons": bool(self.options.prog_weapons.value), - "rando_item_button": bool(self.options.rando_item_button.value) + "rando_item_button": bool(self.options.rando_item_button.value), + "route_required": int(self.options.route_required.value), + "temy_include": int(self.options.temy_include.value) + } def get_filler_item_name(self): @@ -220,16 +223,7 @@ def UndertaleRegion(region_name: str, exits=[]): link_undertale_areas(self.multiworld, self.player) def fill_slot_data(self): - slot_data = self._get_undertale_data() - for option_name in self.options.as_dict(): - option = getattr(self.multiworld, option_name)[self.player] - if (option_name == "rando_love" or option_name == "rando_stats") and \ - self.options.route_required != "genocide" and \ - self.options.route_required != "all_routes": - option.value = False - if slot_data.get(option_name, None) is None and type(option.value) in {str, int}: - slot_data[option_name] = int(option.value) - return slot_data + return self._get_undertale_data() def create_item(self, name: str) -> Item: item_data = item_table[name]