From e0d31010664cc03e24900ccd7f4216c69647feac Mon Sep 17 00:00:00 2001 From: Mysteryem Date: Tue, 20 May 2025 20:23:44 +0100 Subject: [PATCH] Core: Remove redundant reachable location counting in swap (#4990) `prev_state` starts off as a copy of `swap_state` and then `swap_state` collects `item_to_place`. Collecting an item must never reduce accessibility (otherwise generation breaks horribly), so it is guaranteed that `swap_state` will always be able to reach at least as many locations as `prev_state`, so `new_loc_count >= prev_loc_count` is always `True`. As a sideeffect of this change, this fixes generation of Pokemon Emerald with locally shuffled Badges/HMs when there are worlds with unconnected entrances present in the multiworld e.g. KH1. This is because this location counting did not respect `single_player_placement=True` and counted reachable locations across the entire multiworld. Fixes #4834 as a sideeffect of removing the redundant code. --- Fill.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/Fill.py b/Fill.py index ff59aa22..d0a42c07 100644 --- a/Fill.py +++ b/Fill.py @@ -138,32 +138,21 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati # to clean that up later, so there is a chance generation fails. if (not single_player_placement or location.player == item_to_place.player) \ and location.can_fill(swap_state, item_to_place, perform_access_check): + # Add this item to the existing placement, and + # add the old item to the back of the queue + spot_to_fill = placements.pop(i) - # Verify placing this item won't reduce available locations, which would be a useless swap. - prev_state = swap_state.copy() - prev_loc_count = len( - multiworld.get_reachable_locations(prev_state)) + swap_count += 1 + swapped_items[placed_item.player, placed_item.name, unsafe] = swap_count - swap_state.collect(item_to_place, True) - new_loc_count = len( - multiworld.get_reachable_locations(swap_state)) + reachable_items[placed_item.player].appendleft( + placed_item) + item_pool.append(placed_item) - if new_loc_count >= prev_loc_count: - # Add this item to the existing placement, and - # add the old item to the back of the queue - spot_to_fill = placements.pop(i) + # cleanup at the end to hopefully get better errors + cleanup_required = True - swap_count += 1 - swapped_items[placed_item.player, placed_item.name, unsafe] = swap_count - - reachable_items[placed_item.player].appendleft( - placed_item) - item_pool.append(placed_item) - - # cleanup at the end to hopefully get better errors - cleanup_required = True - - break + break # Item can't be placed here, restore original item location.item = placed_item