GER: Use Itempool Count for Minimal handling (#4649)

* uses itempool count vs unfilled location count instead of counting prog_items values which could have custom counters

* move unfilled location check to before can_reach

* add tests for successful minimal GER call with extra collect override prog_items in the pool to regression test issue fixed in this PR
This commit is contained in:
qwint
2025-02-16 14:21:09 -05:00
committed by GitHub
parent efd5004330
commit 34795b598a
2 changed files with 34 additions and 2 deletions

View File

@@ -378,13 +378,14 @@ def randomize_entrances(
and world.multiworld.has_beaten_game(er_state.collection_state, world.player): and world.multiworld.has_beaten_game(er_state.collection_state, world.player):
# ensure that we have enough locations to place our progression # ensure that we have enough locations to place our progression
accessible_location_count = 0 accessible_location_count = 0
prog_item_count = sum(er_state.collection_state.prog_items[world.player].values()) prog_item_count = len([item for item in world.multiworld.itempool if item.advancement and item.player == world.player])
# short-circuit location checking in this case # short-circuit location checking in this case
if prog_item_count == 0: if prog_item_count == 0:
return True return True
for region in er_state.placed_regions: for region in er_state.placed_regions:
for loc in region.locations: for loc in region.locations:
if loc.can_reach(er_state.collection_state): if not loc.item and loc.can_reach(er_state.collection_state):
# don't count locations with preplaced items
accessible_location_count += 1 accessible_location_count += 1
if accessible_location_count >= prog_item_count: if accessible_location_count >= prog_item_count:
perform_validity_check = False perform_validity_check = False

View File

@@ -311,6 +311,37 @@ class TestRandomizeEntrances(unittest.TestCase):
self.assertEqual([], [exit_ for region in multiworld.get_regions() self.assertEqual([], [exit_ for region in multiworld.get_regions()
for exit_ in region.exits if not exit_.connected_region]) for exit_ in region.exits if not exit_.connected_region])
def test_minimal_entrance_rando_with_collect_override(self):
"""
tests that entrance randomization can complete with minimal accessibility and unreachable exits
when the world defines a collect override that add extra values to prog_items
"""
multiworld = generate_test_multiworld()
multiworld.worlds[1].options.accessibility = Accessibility.from_any(Accessibility.option_minimal)
multiworld.completion_condition[1] = lambda state: state.can_reach("region24", player=1)
generate_disconnected_region_grid(multiworld, 5, 1)
prog_items = generate_items(10, 1, True)
multiworld.itempool += prog_items
filler_items = generate_items(15, 1, False)
multiworld.itempool += filler_items
e = multiworld.get_entrance("region1_right", 1)
set_rule(e, lambda state: False)
old_collect = multiworld.worlds[1].collect
def new_collect(state, item):
old_collect(state, item)
state.prog_items[item.player]["counter"] += 300
multiworld.worlds[1].collect = new_collect
randomize_entrances(multiworld.worlds[1], False, directionally_matched_group_lookup)
self.assertEqual([], [entrance for region in multiworld.get_regions()
for entrance in region.entrances if not entrance.parent_region])
self.assertEqual([], [exit_ for region in multiworld.get_regions()
for exit_ in region.exits if not exit_.connected_region])
def test_restrictive_region_requirement_does_not_fail(self): def test_restrictive_region_requirement_does_not_fail(self):
multiworld = generate_test_multiworld() multiworld = generate_test_multiworld()
generate_disconnected_region_grid(multiworld, 2, 1) generate_disconnected_region_grid(multiworld, 2, 1)