Allow fill_hook to remove things from the pool

This commit is contained in:
Brad Humphrey 2022-01-21 20:34:59 -07:00 committed by Fabian Dill
parent 102c1fecb6
commit 00ccecac9c
2 changed files with 35 additions and 10 deletions

25
Fill.py
View File

@ -110,16 +110,6 @@ def distribute_items_restrictive(world: MultiWorld, fill_locations=None):
world.random.shuffle(fill_locations) world.random.shuffle(fill_locations)
locations: dict[LocationProgressType, list[Location]] = {
type: [] for type in LocationProgressType}
for loc in fill_locations:
locations[loc.progress_type].append(loc)
prioritylocations = locations[LocationProgressType.PRIORITY]
defaultlocations = locations[LocationProgressType.DEFAULT]
excludedlocations = locations[LocationProgressType.EXCLUDED]
# get items to distribute # get items to distribute
world.random.shuffle(world.itempool) world.random.shuffle(world.itempool)
progitempool = [] progitempool = []
@ -143,6 +133,18 @@ def distribute_items_restrictive(world: MultiWorld, fill_locations=None):
call_all(world, "fill_hook", progitempool, nonexcludeditempool, call_all(world, "fill_hook", progitempool, nonexcludeditempool,
localrestitempool, nonlocalrestitempool, restitempool, fill_locations) localrestitempool, nonlocalrestitempool, restitempool, fill_locations)
locations: dict[LocationProgressType, list[Location]] = {
type: [] for type in LocationProgressType}
for loc in fill_locations:
locations[loc.progress_type].append(loc)
logging.warning("Locations: " + str(len(fill_locations)))
logging.warning("Items: " + str(len(world.itempool)))
prioritylocations = locations[LocationProgressType.PRIORITY]
defaultlocations = locations[LocationProgressType.DEFAULT]
excludedlocations = locations[LocationProgressType.EXCLUDED]
locationDeficit = len(progitempool) - len(prioritylocations) locationDeficit = len(progitempool) - len(prioritylocations)
if locationDeficit > 0: if locationDeficit > 0:
if locationDeficit > len(defaultlocations): if locationDeficit > len(defaultlocations):
@ -157,6 +159,9 @@ def distribute_items_restrictive(world: MultiWorld, fill_locations=None):
if progitempool: if progitempool:
fill_restrictive(world, world.state, defaultlocations, progitempool) fill_restrictive(world, world.state, defaultlocations, progitempool)
if(len(progitempool) > 0):
raise FillError(
f'Not enough locations for progress items. There are {len(progitempool)} more items than locations')
if nonexcludeditempool: if nonexcludeditempool:
world.random.shuffle(defaultlocations) world.random.shuffle(defaultlocations)

View File

@ -487,6 +487,26 @@ class TestDistributeItemsRestrictive(unittest.TestCase):
self.assertTrue(player3.locations[2].item.advancement) self.assertTrue(player3.locations[2].item.advancement)
self.assertTrue(player3.locations[3].item.advancement) self.assertTrue(player3.locations[3].item.advancement)
def test_can_remove_locations_in_fill_hook(self):
multi_world = generate_multi_world()
player1 = generate_player_data(
multi_world, 1, 4, prog_item_count=2, basic_item_count=2)
removed_item: list[Item] = []
removed_location: list[Location] = []
def fill_hook(progitempool, nonexcludeditempool, localrestitempool, nonlocalrestitempool, restitempool, fill_locations):
removed_item.append(restitempool.pop(0))
removed_location.append(fill_locations.pop(0))
multi_world.worlds[player1.id].fill_hook = fill_hook
distribute_items_restrictive(multi_world)
self.assertIsNone(removed_item[0].location)
self.assertIsNone(removed_location[0].item)
class TestBalanceMultiworldProgression(unittest.TestCase): class TestBalanceMultiworldProgression(unittest.TestCase):
def assertRegionContains(self, region: Region, item: Item): def assertRegionContains(self, region: Region, item: Item):