diff --git a/BaseClasses.py b/BaseClasses.py index 092f330bcb..95f24af265 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -863,19 +863,15 @@ class CollectionState(): ) # 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 @@ -1427,7 +1423,7 @@ class Spoiler: # 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 5185bbb60e..15d5842e29 100644 --- a/Fill.py +++ b/Fill.py @@ -12,7 +12,12 @@ from worlds.generic.Rules import add_item_rule 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 distribute_items_restrictive(multiworld: MultiWorld, 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 distribute_items_restrictive(multiworld: MultiWorld, 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 e4b65be93a..6b66b2a3a6 100644 --- a/Launcher.py +++ b/Launcher.py @@ -266,7 +266,7 @@ def run_gui(): 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 ce054dcd39..edae5d7b19 100644 --- a/Main.py +++ b/Main.py @@ -11,7 +11,8 @@ from typing import Dict, List, Optional, Set, Tuple, Union 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 main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No 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 d040828509..ecde6275f1 100644 --- a/Options.py +++ b/Options.py @@ -1236,6 +1236,7 @@ class CommonOptions(metaclass=OptionsMetaProperty): :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 generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], ge 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 5c2d241cbb..9fb223af2a 100644 --- a/test/bases.py +++ b/test/bases.py @@ -23,7 +23,7 @@ class TestBase(unittest.TestCase): 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 5289cac6c3..8415ac4c84 100644 --- a/test/multiworld/test_multiworlds.py +++ b/test/multiworld/test_multiworlds.py @@ -55,7 +55,7 @@ class TestAllGamesMultiworld(MultiworldTestBase): 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 @@ class TestAllGamesMultiworld(MultiworldTestBase): 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/alttp/test/dungeons/TestDungeon.py b/worlds/alttp/test/dungeons/TestDungeon.py index 91fc462c4e..796bfeec3f 100644 --- a/worlds/alttp/test/dungeons/TestDungeon.py +++ b/worlds/alttp/test/dungeons/TestDungeon.py @@ -54,7 +54,7 @@ class TestDungeon(LTTPTestBase): 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 5474f58b82..81e2540bac 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 @@ item_data_table: Dict[str, CliqueItemData] = { "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 144becae53..900b497eb4 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 @@ location_data_table: Dict[str, CliqueLocationData] = { "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 7976dcb621..d88a128990 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 5ae1d2c68e..63ecd4e9e1 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 b5cc74d94a..3d06e477eb 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 @@ class CliqueWorld(World): 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 @@ class CliqueWorld(World): # 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 bbdc30490c..058fdbed00 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 89f10a5a2d..24be303f82 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -1388,7 +1388,7 @@ class OOTWorld(World): 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/stardew_valley/test/TestCrops.py b/worlds/stardew_valley/test/TestCrops.py index 38b736367b..362e6bf27e 100644 --- a/worlds/stardew_valley/test/TestCrops.py +++ b/worlds/stardew_valley/test/TestCrops.py @@ -11,10 +11,10 @@ class TestCropsanityRules(SVTestBase): 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 fe1bfb5f30..bfa58dd340 100644 --- a/worlds/stardew_valley/test/TestDynamicGoals.py +++ b/worlds/stardew_valley/test/TestDynamicGoals.py @@ -12,29 +12,29 @@ from ..strings.wallet_item_names import Wallet 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 65f7352a5e..da00a0f43e 100644 --- a/worlds/stardew_valley/test/TestLogic.py +++ b/worlds/stardew_valley/test/TestLogic.py @@ -12,7 +12,7 @@ from ..options import BundleRandomization 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 7e82ea91e4..c2c2a6a20b 100644 --- a/worlds/stardew_valley/test/__init__.py +++ b/worlds/stardew_valley/test/__init__.py @@ -257,16 +257,16 @@ class SVTestBase(RuleAssertMixin, WorldTestBase, SVTestCase): 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 c1c24bdf75..9717283454 100644 --- a/worlds/stardew_valley/test/assertion/world_assert.py +++ b/worlds/stardew_valley/test/assertion/world_assert.py @@ -33,14 +33,14 @@ class WorldAssertMixin(RuleAssertMixin, TestCase): 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 fb62a45637..2922ecfb5d 100644 --- a/worlds/stardew_valley/test/rules/TestArcades.py +++ b/worlds/stardew_valley/test/rules/TestArcades.py @@ -19,8 +19,8 @@ class TestArcadeMachinesLogic(SVTestBase): 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 @@ class TestArcadeMachinesLogic(SVTestBase): 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 @@ class TestArcadeMachinesLogic(SVTestBase): 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 @@ class TestArcadeMachinesLogic(SVTestBase): 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 @@ class TestArcadeMachinesLogic(SVTestBase): 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 b00e4138a1..2c276d8b5c 100644 --- a/worlds/stardew_valley/test/rules/TestBuildings.py +++ b/worlds/stardew_valley/test/rules/TestBuildings.py @@ -23,11 +23,11 @@ class TestBuildingLogic(SVTestBase): 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 @@ class TestBuildingLogic(SVTestBase): 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 @@ class TestBuildingLogic(SVTestBase): 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 81a91d1e74..7ab9d61cb9 100644 --- a/worlds/stardew_valley/test/rules/TestCookingRecipes.py +++ b/worlds/stardew_valley/test/rules/TestCookingRecipes.py @@ -17,14 +17,14 @@ class TestRecipeLearnLogic(SVTestBase): 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 @@ class TestRecipeReceiveLogic(SVTestBase): 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 @@ class TestRecipeReceiveLogic(SVTestBase): 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 59d41f6a63..93c325ae5c 100644 --- a/worlds/stardew_valley/test/rules/TestCraftingRecipes.py +++ b/worlds/stardew_valley/test/rules/TestCraftingRecipes.py @@ -25,7 +25,7 @@ class TestCraftsanityLogic(SVTestBase): 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 @@ class TestCraftsanityLogic(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("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 @@ class TestNoCraftsanityLogic(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("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 84ceac50ff..984a3ebc38 100644 --- a/worlds/stardew_valley/test/rules/TestDonations.py +++ b/worlds/stardew_valley/test/rules/TestDonations.py @@ -18,7 +18,7 @@ class TestDonationLogicAll(SVTestBase): 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 @@ class TestDonationLogicRandomized(SVTestBase): 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 @@ class TestDonationLogicMilestones(SVTestBase): 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 43c5e55c7f..fb186ca994 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 378933b7d7..973d8d3ada 100644 --- a/worlds/stardew_valley/test/rules/TestShipping.py +++ b/worlds/stardew_valley/test/rules/TestShipping.py @@ -76,7 +76,7 @@ class TestShipsanityEverything(SVTestBase): 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 a1fb152812..5f0fe8ef3f 100644 --- a/worlds/stardew_valley/test/rules/TestTools.py +++ b/worlds/stardew_valley/test/rules/TestTools.py @@ -21,30 +21,30 @@ class TestProgressiveToolsLogic(SVTestBase): 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 @@ class TestProgressiveToolsLogic(SVTestBase): 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 @@ class TestProgressiveToolsLogic(SVTestBase): 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 @@ class TestToolVanillaRequiresBlacksmith(SVTestBase): 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 @@ class TestToolVanillaRequiresBlacksmith(SVTestBase): 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 77887f8eca..972170b93c 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 @@ class TestWeaponsLogic(SVTestBase): 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 86839f0f21..f99dd76155 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/tunic/__init__.py b/worlds/tunic/__init__.py index 5e8cd87975..ea5c4c412a 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -220,8 +220,8 @@ class TunicWorld(World): player_dir = "<->" if player_cxn.direction == "both" else "-->" raise OptionError(f"TUNIC: Conflict between seed group {group}'s plando " f"connection {group_cxn.entrance} {group_dir} {group_cxn.exit} and " - f"{tunic.multiworld.get_player_name(tunic.player)}'s plando " - f"connection {player_cxn.entrance} {player_dir} {player_cxn.exit}") + f"{tunic.player_name}'s plando connection " + f"{player_cxn.entrance} {player_dir} {player_cxn.exit}") if new_cxn: cls.seed_groups[group]["plando"].append(player_cxn) @@ -254,17 +254,17 @@ class TunicWorld(World): 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 @@ -364,15 +364,15 @@ class TunicWorld(World): 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) @@ -420,10 +420,8 @@ class TunicWorld(World): 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): @@ -496,7 +494,9 @@ class TunicWorld(World): 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_scripts.py b/worlds/tunic/er_scripts.py index e1a63060ef..2f1ef7f470 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -183,7 +183,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[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() laurels_zips = world.options.laurels_zips.value ice_grappling = world.options.ice_grappling.value diff --git a/worlds/undertale/__init__.py b/worlds/undertale/__init__.py index 9084c77b00..9f09bb3452 100644 --- a/worlds/undertale/__init__.py +++ b/worlds/undertale/__init__.py @@ -67,12 +67,15 @@ class UndertaleWorld(World): "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 @@ class UndertaleWorld(World): 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]