diff --git a/BaseClasses.py b/BaseClasses.py index 9bf5fccb..a1c1e9c3 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -254,7 +254,7 @@ class MultiWorld(): self._all_state = ret return ret - def get_items(self) -> list: + def get_items(self) -> List[Item]: return [loc.item for loc in self.get_filled_locations()] + self.itempool def find_item_locations(self, item, player: int) -> List[Location]: diff --git a/Fill.py b/Fill.py index 9771432d..95a827d0 100644 --- a/Fill.py +++ b/Fill.py @@ -38,7 +38,8 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations, for items in reachable_items.values() if items] for item in items_to_place: itempool.remove(item) - maximum_exploration_state = sweep_from_pool(base_state, itempool + unplaced_items) + maximum_exploration_state = sweep_from_pool( + base_state, itempool + unplaced_items) has_beaten_game = world.has_beaten_game(maximum_exploration_state) @@ -113,7 +114,7 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations, world.push_item(spot_to_fill, item_to_place, False) spot_to_fill.locked = lock placements.append(spot_to_fill) - spot_to_fill.event = True + spot_to_fill.event = item_to_place.advancement if len(unplaced_items) > 0 and len(locations) > 0: # There are leftover unplaceable items and locations that won't accept them @@ -178,8 +179,8 @@ def distribute_items_restrictive(world: MultiWorld): if nonexcludeditempool: world.random.shuffle(defaultlocations) # needs logical fill to not conflict with local items - nonexcludeditempool, defaultlocations = fast_fill( - world, nonexcludeditempool, defaultlocations) + fill_restrictive( + world, world.state, defaultlocations, nonexcludeditempool) if nonexcludeditempool: raise FillError( f'Not enough locations for non-excluded items. There are {len(nonexcludeditempool)} more items than locations') diff --git a/test/general/TestFill.py b/test/general/TestFill.py index f68e06bf..80b549a1 100644 --- a/test/general/TestFill.py +++ b/test/general/TestFill.py @@ -3,7 +3,7 @@ import unittest from worlds.AutoWorld import World from Fill import FillError, balance_multiworld_progression, fill_restrictive, distribute_items_restrictive from BaseClasses import Entrance, LocationProgressType, MultiWorld, Region, RegionType, Item, Location -from worlds.generic.Rules import CollectionRule, set_rule +from worlds.generic.Rules import CollectionRule, locality_rules, set_rule def generate_multi_world(players: int = 1) -> MultiWorld: @@ -370,9 +370,13 @@ class TestDistributeItemsRestrictive(unittest.TestCase): distribute_items_restrictive(multi_world) self.assertEqual(locations[0].item, basic_items[0]) + self.assertFalse(locations[0].event) self.assertEqual(locations[1].item, prog_items[0]) + self.assertTrue(locations[1].event) self.assertEqual(locations[2].item, prog_items[1]) + self.assertTrue(locations[2].event) self.assertEqual(locations[3].item, basic_items[1]) + self.assertFalse(locations[3].event) def test_excluded_distribute(self): multi_world = generate_multi_world() @@ -557,6 +561,27 @@ class TestDistributeItemsRestrictive(unittest.TestCase): self.assertEqual(location.item, items[4]) + def test_non_excluded_local_items(self): + multi_world = generate_multi_world(2) + player1 = generate_player_data( + multi_world, 1, location_count=5, basic_item_count=5) + player2 = generate_player_data( + multi_world, 2, location_count=5, basic_item_count=5) + + for item in multi_world.get_items(): + item.never_exclude = True + + multi_world.local_items[player1.id].value = set(names(player1.basic_items)) + multi_world.local_items[player2.id].value = set(names(player2.basic_items)) + locality_rules(multi_world, player1.id) + locality_rules(multi_world, player2.id) + + distribute_items_restrictive(multi_world) + + for item in multi_world.get_items(): + self.assertEqual(item.player, item.location.player) + self.assertFalse(item.location.event, False) + class TestBalanceMultiworldProgression(unittest.TestCase): def assertRegionContains(self, region: Region, item: Item):