diff --git a/worlds/pokemon_rb/__init__.py b/worlds/pokemon_rb/__init__.py index 809179cbef..644aa1ed9c 100644 --- a/worlds/pokemon_rb/__init__.py +++ b/worlds/pokemon_rb/__init__.py @@ -111,6 +111,7 @@ class PokemonRedBlueWorld(World): self.dexsanity_table = [] self.trainersanity_table = [] self.local_locs = [] + self.pc_item = None @classmethod def stage_assert_generate(cls, multiworld: MultiWorld): @@ -289,7 +290,9 @@ class PokemonRedBlueWorld(World): multiworld.random.shuffle(itempool) unplaced_items = [] for i, item in enumerate(itempool): - if item.player == loc.player and loc.can_fill(multiworld.state, item, False): + if ((item.player == loc.player or (item.player in multiworld.groups + and loc.player in multiworld.groups[item.player]["players"])) + and loc.can_fill(multiworld.state, item, False)): if item.advancement: pool = progitempool elif item.useful: @@ -308,8 +311,6 @@ class PokemonRedBlueWorld(World): break else: unplaced_items.append(item) - else: - raise FillError(f"Pokemon Red and Blue local item fill failed for player {loc.player}: could not place {item.name}") progitempool += [item for item in unplaced_items if item.advancement] usefulitempool += [item for item in unplaced_items if item.useful] filleritempool += [item for item in unplaced_items if (not item.advancement) and (not item.useful)] @@ -446,15 +447,12 @@ class PokemonRedBlueWorld(World): if loc.item is None: locs.add(loc) - if not self.options.key_items_only: - loc = self.multiworld.get_location("Player's House 2F - Player's PC", self.player) - if loc.item is None: - locs.add(loc) - for loc in sorted(locs): if loc.name in self.options.priority_locations.value: add_item_rule(loc, lambda i: i.advancement) - add_item_rule(loc, lambda i: i.player == self.player) + add_item_rule(loc, lambda i: i.player == self.player + or (i.player in self.multiworld.groups + and self.player in self.multiworld.groups[i.player]["players"])) if self.options.old_man == "early_parcel" and loc.name != "Player's House 2F - Player's PC": add_item_rule(loc, lambda i: i.name != "Oak's Parcel") @@ -520,6 +518,14 @@ class PokemonRedBlueWorld(World): else: raise Exception("Failed to remove corresponding item while deleting unreachable Dexsanity location") + if not self.options.key_items_only: + loc = self.multiworld.get_location("Player's House 2F - Player's PC", self.player) + # Absolutely cannot have another player's item + if loc.item is not None and loc.item.player != self.player: + self.multiworld.itempool.append(loc.item) + loc.item = None + loc.place_locked_item(self.pc_item) + @classmethod def stage_post_fill(cls, multiworld): # Convert all but one of each instance of a wild Pokemon to useful classification. diff --git a/worlds/pokemon_rb/regions.py b/worlds/pokemon_rb/regions.py index d4b8a8f506..aef0b945a2 100644 --- a/worlds/pokemon_rb/regions.py +++ b/worlds/pokemon_rb/regions.py @@ -1579,6 +1579,18 @@ def create_regions(world): world.item_pool.append(item) world.random.shuffle(world.item_pool) + if not world.options.key_items_only: + if "Player's House 2F - Player's PC" in world.options.exclude_locations: + acceptable_item = lambda item: item.excludable + elif "Player's House 2F - Player's PC" in world.options.priority_locations: + acceptable_item = lambda item: item.advancement + else: + acceptable_item = lambda item: True + for i, item in enumerate(world.item_pool): + if acceptable_item(item): + world.pc_item = world.item_pool.pop(i) + break + advancement_items = [item.name for item in world.item_pool if item.advancement] \ + [item.name for item in world.multiworld.precollected_items[world.player] if item.advancement]