From 7f35eb88675396185f71d0e386c0c3b0f040186b Mon Sep 17 00:00:00 2001 From: Alchav <59858495+Alchav@users.noreply.github.com> Date: Sun, 16 Mar 2025 12:33:24 -0400 Subject: [PATCH] =?UTF-8?q?Pok=C3=A9mon=20R/B:=20Allow=20generating=20with?= =?UTF-8?q?=20all=20items=20linked=20(#4330)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Pokémon R/B: Allow generating with all items linked * check priority/excluded locations for pc_item * Update regions.py * Un-remove regions.py code --- worlds/pokemon_rb/__init__.py | 24 +++++++++++++++--------- worlds/pokemon_rb/regions.py | 12 ++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/worlds/pokemon_rb/__init__.py b/worlds/pokemon_rb/__init__.py index 809179cb..644aa1ed 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 d4b8a8f5..aef0b945 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]