Core: replace `Location.event` with `advancement` property (#2871)

This commit is contained in:
Aaron Wagener 2024-04-14 13:37:48 -05:00 committed by GitHub
parent f67e8497e0
commit 842a15fd3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 79 additions and 144 deletions

View File

@ -437,7 +437,7 @@ class MultiWorld():
location.item = item location.item = item
item.location = location item.location = location
if collect: if collect:
self.state.collect(item, location.event, location) self.state.collect(item, location.advancement, location)
logging.debug('Placed %s at %s', item, location) logging.debug('Placed %s at %s', item, location)
@ -584,8 +584,7 @@ class MultiWorld():
def location_relevant(location: Location): def location_relevant(location: Location):
"""Determine if this location is relevant to sweep.""" """Determine if this location is relevant to sweep."""
if location.progress_type != LocationProgressType.EXCLUDED \ if location.progress_type != LocationProgressType.EXCLUDED \
and (location.player in players["locations"] or location.event and (location.player in players["locations"] or location.advancement):
or (location.item and location.item.advancement)):
return True return True
return False return False
@ -730,7 +729,7 @@ class CollectionState():
locations = self.multiworld.get_filled_locations() locations = self.multiworld.get_filled_locations()
reachable_events = True reachable_events = True
# since the loop has a good chance to run more than once, only filter the events once # since the loop has a good chance to run more than once, only filter the events once
locations = {location for location in locations if location.event and location not in self.events and locations = {location for location in locations if location.advancement and location not in self.events and
not key_only or getattr(location.item, "locked_dungeon_item", False)} not key_only or getattr(location.item, "locked_dungeon_item", False)}
while reachable_events: while reachable_events:
reachable_events = {location for location in locations if location.can_reach(self)} reachable_events = {location for location in locations if location.can_reach(self)}
@ -1020,7 +1019,6 @@ class Location:
name: str name: str
address: Optional[int] address: Optional[int]
parent_region: Optional[Region] parent_region: Optional[Region]
event: bool = False
locked: bool = False locked: bool = False
show_in_spoiler: bool = True show_in_spoiler: bool = True
progress_type: LocationProgressType = LocationProgressType.DEFAULT progress_type: LocationProgressType = LocationProgressType.DEFAULT
@ -1051,7 +1049,6 @@ class Location:
raise Exception(f"Location {self} already filled.") raise Exception(f"Location {self} already filled.")
self.item = item self.item = item
item.location = self item.location = self
self.event = item.advancement
self.locked = True self.locked = True
def __repr__(self): def __repr__(self):
@ -1067,6 +1064,10 @@ class Location:
def __lt__(self, other: Location): def __lt__(self, other: Location):
return (self.player, self.name) < (other.player, other.name) return (self.player, self.name) < (other.player, other.name)
@property
def advancement(self) -> bool:
return self.item is not None and self.item.advancement
@property @property
def is_event(self) -> bool: def is_event(self) -> bool:
"""Returns True if the address of this location is None, denoting it is an Event Location.""" """Returns True if the address of this location is None, denoting it is an Event Location."""

10
Fill.py
View File

@ -159,7 +159,6 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
multiworld.push_item(spot_to_fill, item_to_place, False) multiworld.push_item(spot_to_fill, item_to_place, False)
spot_to_fill.locked = lock spot_to_fill.locked = lock
placements.append(spot_to_fill) placements.append(spot_to_fill)
spot_to_fill.event = item_to_place.advancement
placed += 1 placed += 1
if not placed % 1000: if not placed % 1000:
_log_fill_progress(name, placed, total) _log_fill_progress(name, placed, total)
@ -310,7 +309,6 @@ def accessibility_corrections(multiworld: MultiWorld, state: CollectionState, lo
pool.append(location.item) pool.append(location.item)
state.remove(location.item) state.remove(location.item)
location.item = None location.item = None
location.event = False
if location in state.events: if location in state.events:
state.events.remove(location) state.events.remove(location)
locations.append(location) locations.append(location)
@ -659,7 +657,7 @@ def balance_multiworld_progression(multiworld: MultiWorld) -> None:
while True: while True:
# Check locations in the current sphere and gather progression items to swap earlier # Check locations in the current sphere and gather progression items to swap earlier
for location in balancing_sphere: for location in balancing_sphere:
if location.event: if location.advancement:
balancing_state.collect(location.item, True, location) balancing_state.collect(location.item, True, location)
player = location.item.player player = location.item.player
# only replace items that end up in another player's world # only replace items that end up in another player's world
@ -716,7 +714,7 @@ def balance_multiworld_progression(multiworld: MultiWorld) -> None:
# sort then shuffle to maintain deterministic behaviour, # sort then shuffle to maintain deterministic behaviour,
# while allowing use of set for better algorithm growth behaviour elsewhere # while allowing use of set for better algorithm growth behaviour elsewhere
replacement_locations = sorted(l for l in checked_locations if not l.event and not l.locked) replacement_locations = sorted(l for l in checked_locations if not l.advancement and not l.locked)
multiworld.random.shuffle(replacement_locations) multiworld.random.shuffle(replacement_locations)
items_to_replace.sort() items_to_replace.sort()
multiworld.random.shuffle(items_to_replace) multiworld.random.shuffle(items_to_replace)
@ -747,7 +745,7 @@ def balance_multiworld_progression(multiworld: MultiWorld) -> None:
sphere_locations.add(location) sphere_locations.add(location)
for location in sphere_locations: for location in sphere_locations:
if location.event: if location.advancement:
state.collect(location.item, True, location) state.collect(location.item, True, location)
checked_locations |= sphere_locations checked_locations |= sphere_locations
@ -768,7 +766,6 @@ def swap_location_item(location_1: Location, location_2: Location, check_locked:
location_2.item, location_1.item = location_1.item, location_2.item location_2.item, location_1.item = location_1.item, location_2.item
location_1.item.location = location_1 location_1.item.location = location_1
location_2.item.location = location_2 location_2.item.location = location_2
location_1.event, location_2.event = location_2.event, location_1.event
def distribute_planned(multiworld: MultiWorld) -> None: def distribute_planned(multiworld: MultiWorld) -> None:
@ -965,7 +962,6 @@ def distribute_planned(multiworld: MultiWorld) -> None:
placement['force']) placement['force'])
for (item, location) in successful_pairs: for (item, location) in successful_pairs:
multiworld.push_item(location, item, collect=False) multiworld.push_item(location, item, collect=False)
location.event = True # flag location to be checked during fill
location.locked = True location.locked = True
logging.debug(f"Plando placed {item} at {location}") logging.debug(f"Plando placed {item} at {location}")
if from_pool: if from_pool:

View File

@ -380,11 +380,6 @@ from BaseClasses import Location
class MyGameLocation(Location): class MyGameLocation(Location):
game: str = "My Game" game: str = "My Game"
# override constructor to automatically mark event locations as such
def __init__(self, player: int, name="", code=None, parent=None) -> None:
super(MyGameLocation, self).__init__(player, name, code, parent)
self.event = code is None
``` ```
in your `__init__.py` or your `locations.py`. in your `__init__.py` or your `locations.py`.

View File

@ -221,7 +221,7 @@ class WorldTestBase(unittest.TestCase):
if isinstance(items, Item): if isinstance(items, Item):
items = (items,) items = (items,)
for item in items: for item in items:
if item.location and item.location.event and item.location in self.multiworld.state.events: if item.location and item.advancement and item.location in self.multiworld.state.events:
self.multiworld.state.events.remove(item.location) self.multiworld.state.events.remove(item.location)
self.multiworld.state.remove(item) self.multiworld.state.remove(item)

View File

@ -80,7 +80,6 @@ def fill_region(multiworld: MultiWorld, region: Region, items: List[Item]) -> Li
return items return items
item = items.pop(0) item = items.pop(0)
multiworld.push_item(location, item, False) multiworld.push_item(location, item, False)
location.event = item.advancement
return items return items
@ -489,7 +488,6 @@ class TestFillRestrictive(unittest.TestCase):
player1 = generate_player_data(multiworld, 1, 1, 1) player1 = generate_player_data(multiworld, 1, 1, 1)
location = player1.locations[0] location = player1.locations[0]
location.address = None location.address = None
location.event = True
item = player1.prog_items[0] item = player1.prog_items[0]
item.code = None item.code = None
location.place_locked_item(item) location.place_locked_item(item)
@ -527,13 +525,13 @@ class TestDistributeItemsRestrictive(unittest.TestCase):
distribute_items_restrictive(multiworld) distribute_items_restrictive(multiworld)
self.assertEqual(locations[0].item, basic_items[1]) self.assertEqual(locations[0].item, basic_items[1])
self.assertFalse(locations[0].event) self.assertFalse(locations[0].advancement)
self.assertEqual(locations[1].item, prog_items[0]) self.assertEqual(locations[1].item, prog_items[0])
self.assertTrue(locations[1].event) self.assertTrue(locations[1].advancement)
self.assertEqual(locations[2].item, prog_items[1]) self.assertEqual(locations[2].item, prog_items[1])
self.assertTrue(locations[2].event) self.assertTrue(locations[2].advancement)
self.assertEqual(locations[3].item, basic_items[0]) self.assertEqual(locations[3].item, basic_items[0])
self.assertFalse(locations[3].event) self.assertFalse(locations[3].advancement)
def test_excluded_distribute(self): def test_excluded_distribute(self):
"""Test that distribute_items_restrictive doesn't put advancement items on excluded locations""" """Test that distribute_items_restrictive doesn't put advancement items on excluded locations"""
@ -746,7 +744,7 @@ class TestDistributeItemsRestrictive(unittest.TestCase):
for item in multiworld.get_items(): for item in multiworld.get_items():
self.assertEqual(item.player, item.location.player) self.assertEqual(item.player, item.location.player)
self.assertFalse(item.location.event, False) self.assertFalse(item.location.advancement, False)
def test_early_items(self) -> None: def test_early_items(self) -> None:
"""Test that the early items API successfully places items early""" """Test that the early items API successfully places items early"""

View File

@ -253,10 +253,8 @@ def generate_itempool(world):
region.locations.append(loc) region.locations.append(loc)
multiworld.push_item(loc, item_factory('Triforce', world), False) multiworld.push_item(loc, item_factory('Triforce', world), False)
loc.event = True
loc.locked = True loc.locked = True
multiworld.get_location('Ganon', player).event = True
multiworld.get_location('Ganon', player).locked = True multiworld.get_location('Ganon', player).locked = True
event_pairs = [ event_pairs = [
('Agahnim 1', 'Beat Agahnim 1'), ('Agahnim 1', 'Beat Agahnim 1'),
@ -273,7 +271,7 @@ def generate_itempool(world):
location = multiworld.get_location(location_name, player) location = multiworld.get_location(location_name, player)
event = item_factory(event_name, world) event = item_factory(event_name, world)
multiworld.push_item(location, event, False) multiworld.push_item(location, event, False)
location.event = location.locked = True location.locked = True
# set up item pool # set up item pool

View File

@ -1193,7 +1193,6 @@ def set_trock_key_rules(world, player):
item = item_factory('Small Key (Turtle Rock)', world.worlds[player]) item = item_factory('Small Key (Turtle Rock)', world.worlds[player])
location = world.get_location('Turtle Rock - Big Key Chest', player) location = world.get_location('Turtle Rock - Big Key Chest', player)
location.place_locked_item(item) location.place_locked_item(item)
location.event = True
toss_junk_item(world, player) toss_junk_item(world, player)
if world.accessibility[player] != 'locations': if world.accessibility[player] != 'locations':

View File

@ -10,10 +10,6 @@ class AdvData(typing.NamedTuple):
class ChecksFinderAdvancement(Location): class ChecksFinderAdvancement(Location):
game: str = "ChecksFinder" game: str = "ChecksFinder"
def __init__(self, player: int, name: str, address: typing.Optional[int], parent):
super().__init__(player, name, address, parent)
self.event = not address
advancement_table = { advancement_table = {
"Tile 1": AdvData(81000, 'Board'), "Tile 1": AdvData(81000, 'Board'),

View File

@ -61,7 +61,7 @@ class DLCqworld(World):
self.precollect_coinsanity() self.precollect_coinsanity()
locations_count = len([location locations_count = len([location
for location in self.multiworld.get_locations(self.player) for location in self.multiworld.get_locations(self.player)
if not location.event]) if not location.advancement])
items_to_exclude = [excluded_items items_to_exclude = [excluded_items
for excluded_items in self.multiworld.precollected_items[self.player]] for excluded_items in self.multiworld.precollected_items[self.player]]

View File

@ -10,7 +10,7 @@ def get_all_item_names(multiworld: MultiWorld) -> List[str]:
def get_all_location_names(multiworld: MultiWorld) -> List[str]: def get_all_location_names(multiworld: MultiWorld) -> List[str]:
return [location.name for location in multiworld.get_locations() if not location.event] return [location.name for location in multiworld.get_locations() if not location.advancement]
def assert_victory_exists(tester: DLCQuestTestBase, multiworld: MultiWorld): def assert_victory_exists(tester: DLCQuestTestBase, multiworld: MultiWorld):
@ -38,5 +38,5 @@ def assert_can_win(tester: DLCQuestTestBase, multiworld: MultiWorld):
def assert_same_number_items_locations(tester: DLCQuestTestBase, multiworld: MultiWorld): def assert_same_number_items_locations(tester: DLCQuestTestBase, multiworld: MultiWorld):
non_event_locations = [location for location in multiworld.get_locations() if not location.event] non_event_locations = [location for location in multiworld.get_locations() if not location.advancement]
tester.assertEqual(len(multiworld.itempool), len(non_event_locations)) tester.assertEqual(len(multiworld.itempool), len(non_event_locations))

View File

@ -90,7 +90,7 @@ def exclusion_rules(multiworld: MultiWorld, player: int, exclude_locations: typi
if loc_name not in multiworld.worlds[player].location_name_to_id: if loc_name not in multiworld.worlds[player].location_name_to_id:
raise Exception(f"Unable to exclude location {loc_name} in player {player}'s world.") from e raise Exception(f"Unable to exclude location {loc_name} in player {player}'s world.") from e
else: else:
if not location.event: if not location.advancement:
location.progress_type = LocationProgressType.EXCLUDED location.progress_type = LocationProgressType.EXCLUDED
else: else:
logging.warning(f"Unable to exclude location {loc_name} in player {player}'s world.") logging.warning(f"Unable to exclude location {loc_name} in player {player}'s world.")

View File

@ -60,13 +60,11 @@ class LinksAwakeningLocation(Location):
def __init__(self, player: int, region, ladxr_item): def __init__(self, player: int, region, ladxr_item):
name = meta_to_name(ladxr_item.metadata) name = meta_to_name(ladxr_item.metadata)
self.event = ladxr_item.event is not None
if self.event:
name = ladxr_item.event
address = None address = None
if not self.event:
if ladxr_item.event is not None:
name = ladxr_item.event
else:
address = locations_to_id[name] address = locations_to_id[name]
super().__init__(player, name, address) super().__init__(player, name, address)
self.parent_region = region self.parent_region = region

View File

@ -154,7 +154,7 @@ class LinksAwakeningWorld(World):
# Place RAFT, other access events # Place RAFT, other access events
for region in regions: for region in regions:
for loc in region.locations: for loc in region.locations:
if loc.event: if loc.address is None:
loc.place_locked_item(self.create_event(loc.ladxr_item.event)) loc.place_locked_item(self.create_event(loc.ladxr_item.event))
# Connect Windfish -> Victory # Connect Windfish -> Victory

View File

@ -9,11 +9,6 @@ from BaseClasses import Location
class MeritousLocation(Location): class MeritousLocation(Location):
game: str = "Meritous" game: str = "Meritous"
def __init__(self, player: int, name: str = '', address: int = None, parent=None):
super(MeritousLocation, self).__init__(player, name, address, parent)
if "Wervyn Anixil" in name or "Defeat" in name:
self.event = True
offset = 593_000 offset = 593_000

View File

@ -44,14 +44,11 @@ class OOTLocation(Location):
self.vanilla_item = vanilla_item self.vanilla_item = vanilla_item
if filter_tags is None: if filter_tags is None:
self.filter_tags = None self.filter_tags = None
else: else:
self.filter_tags = list(filter_tags) self.filter_tags = list(filter_tags)
self.never = False # no idea what this does self.never = False # no idea what this does
self.disabled = DisableType.ENABLED self.disabled = DisableType.ENABLED
if type == 'Event':
self.event = True
@property @property
def dungeon(self): def dungeon(self):
return self.parent_region.dungeon return self.parent_region.dungeon

View File

@ -717,7 +717,6 @@ class OOTWorld(World):
item = self.create_item(name, allow_arbitrary_name=True) item = self.create_item(name, allow_arbitrary_name=True)
self.multiworld.push_item(location, item, collect=False) self.multiworld.push_item(location, item, collect=False)
location.locked = True location.locked = True
location.event = True
if name not in item_table: if name not in item_table:
location.internal = True location.internal = True
return item return item
@ -842,7 +841,7 @@ class OOTWorld(World):
all_state.sweep_for_events(locations=all_locations) all_state.sweep_for_events(locations=all_locations)
reachable = self.multiworld.get_reachable_locations(all_state, self.player) reachable = self.multiworld.get_reachable_locations(all_state, self.player)
unreachable = [loc for loc in all_locations if unreachable = [loc for loc in all_locations if
(loc.internal or loc.type == 'Drop') and loc.event and loc.locked and loc not in reachable] (loc.internal or loc.type == 'Drop') and loc.address is None and loc.locked and loc not in reachable]
for loc in unreachable: for loc in unreachable:
loc.parent_region.locations.remove(loc) loc.parent_region.locations.remove(loc)
# Exception: Sell Big Poe is an event which is only reachable if Bottle with Big Poe is in the item pool. # Exception: Sell Big Poe is an event which is only reachable if Bottle with Big Poe is in the item pool.
@ -972,7 +971,6 @@ class OOTWorld(World):
for location in song_locations: for location in song_locations:
location.item = None location.item = None
location.locked = False location.locked = False
location.event = False
else: else:
break break

View File

@ -115,8 +115,6 @@ class Overcooked2World(World):
region, region,
) )
location.event = is_event
if priority: if priority:
location.progress_type = LocationProgressType.PRIORITY location.progress_type = LocationProgressType.PRIORITY
else: else:

View File

@ -265,7 +265,6 @@ class PokemonRedBlueWorld(World):
state = sweep_from_pool(multiworld.state, progitempool + unplaced_items) state = sweep_from_pool(multiworld.state, progitempool + unplaced_items)
if (not item.advancement) or state.can_reach(loc, "Location", loc.player): if (not item.advancement) or state.can_reach(loc, "Location", loc.player):
multiworld.push_item(loc, item, False) multiworld.push_item(loc, item, False)
loc.event = item.advancement
fill_locations.remove(loc) fill_locations.remove(loc)
break break
else: else:

View File

@ -197,7 +197,6 @@ def process_pokemon_locations(self):
mon = randomize_pokemon(self, original_mon, mons_list, 2, self.multiworld.random) mon = randomize_pokemon(self, original_mon, mons_list, 2, self.multiworld.random)
placed_mons[mon] += 1 placed_mons[mon] += 1
location.item = self.create_item(mon) location.item = self.create_item(mon)
location.event = True
location.locked = True location.locked = True
location.item.location = location location.item.location = location
locations.append(location) locations.append(location)
@ -269,7 +268,6 @@ def process_pokemon_locations(self):
for slot in encounter_slots: for slot in encounter_slots:
location = self.multiworld.get_location(slot.name, self.player) location = self.multiworld.get_location(slot.name, self.player)
location.item = self.create_item(slot.original_item) location.item = self.create_item(slot.original_item)
location.event = True
location.locked = True location.locked = True
location.item.location = location location.item.location = location
placed_mons[location.item.name] += 1 placed_mons[location.item.name] += 1

View File

@ -1540,7 +1540,6 @@ def create_regions(self):
item = self.create_filler() item = self.create_filler()
elif location.original_item == "Pokedex": elif location.original_item == "Pokedex":
if self.multiworld.randomize_pokedex[self.player] == "vanilla": if self.multiworld.randomize_pokedex[self.player] == "vanilla":
location_object.event = True
event = True event = True
item = self.create_item("Pokedex") item = self.create_item("Pokedex")
elif location.original_item == "Moon Stone" and self.multiworld.stonesanity[self.player]: elif location.original_item == "Moon Stone" and self.multiworld.stonesanity[self.player]:

0
worlds/sc2wol/Regions.py Normal file
View File

View File

@ -527,7 +527,6 @@ class SMZ3World(World):
if (loc.item.player == self.player and loc.always_allow(state, loc.item)): if (loc.item.player == self.player and loc.always_allow(state, loc.item)):
loc.item.classification = ItemClassification.filler loc.item.classification = ItemClassification.filler
loc.item.item.Progression = False loc.item.item.Progression = False
loc.item.location.event = False
self.unreachable.append(loc) self.unreachable.append(loc)
def get_filler_item_name(self) -> str: def get_filler_item_name(self) -> str:
@ -573,7 +572,6 @@ class SMZ3World(World):
break break
assert itemFromPool is not None, "Can't find anymore item(s) to pre fill GT" assert itemFromPool is not None, "Can't find anymore item(s) to pre fill GT"
self.multiworld.push_item(loc, itemFromPool, False) self.multiworld.push_item(loc, itemFromPool, False)
loc.event = False
toRemove.sort(reverse = True) toRemove.sort(reverse = True)
for i in toRemove: for i in toRemove:
self.multiworld.itempool.pop(i) self.multiworld.itempool.pop(i)

View File

@ -486,4 +486,3 @@ class SoELocation(Location):
super().__init__(player, name, address, parent) super().__init__(player, name, address, parent)
# unconditional assignments favor a split dict, saving memory # unconditional assignments favor a split dict, saving memory
self.progress_type = LocationProgressType.EXCLUDED if exclude else LocationProgressType.DEFAULT self.progress_type = LocationProgressType.EXCLUDED if exclude else LocationProgressType.DEFAULT
self.event = not address

View File

@ -92,12 +92,6 @@ def create_region(world: MultiWorld, player: int, name: str, locations=None, exi
class SpireLocation(Location): class SpireLocation(Location):
game: str = "Slay the Spire" game: str = "Slay the Spire"
def __init__(self, player: int, name: str, address=None, parent=None):
super(SpireLocation, self).__init__(player, name, address, parent)
if address is None:
self.event = True
self.locked = True
class SpireItem(Item): class SpireItem(Item):
game = "Slay the Spire" game = "Slay the Spire"

View File

@ -30,10 +30,6 @@ client_version = 0
class StardewLocation(Location): class StardewLocation(Location):
game: str = "Stardew Valley" game: str = "Stardew Valley"
def __init__(self, player: int, name: str, address: Optional[int], parent=None):
super().__init__(player, name, address, parent)
self.event = not address
class StardewItem(Item): class StardewItem(Item):
game: str = "Stardew Valley" game: str = "Stardew Valley"
@ -144,7 +140,7 @@ class StardewValleyWorld(World):
locations_count = len([location locations_count = len([location
for location in self.multiworld.get_locations(self.player) for location in self.multiworld.get_locations(self.player)
if not location.event]) if location.address is not None])
created_items = create_items(self.create_item, self.delete_item, locations_count, items_to_exclude, self.options, created_items = create_items(self.create_item, self.delete_item, locations_count, items_to_exclude, self.options,
self.random) self.random)

View File

@ -371,8 +371,7 @@ class TestLocationGeneration(SVTestBase):
def test_all_location_created_are_in_location_table(self): def test_all_location_created_are_in_location_table(self):
for location in self.get_real_locations(): for location in self.get_real_locations():
if not location.event: self.assertIn(location.name, location_table)
self.assertIn(location.name, location_table)
class TestMinLocationAndMaxItem(SVTestBase): class TestMinLocationAndMaxItem(SVTestBase):
@ -771,11 +770,10 @@ class TestShipsanityNone(SVTestBase):
} }
def test_no_shipsanity_locations(self): def test_no_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event: with self.subTest(location.name):
with self.subTest(location.name): self.assertFalse("Shipsanity" in location.name)
self.assertFalse("Shipsanity" in location.name) self.assertNotIn(LocationTags.SHIPSANITY, location_table[location.name].tags)
self.assertNotIn(LocationTags.SHIPSANITY, location_table[location.name].tags)
class TestShipsanityCrops(SVTestBase): class TestShipsanityCrops(SVTestBase):
@ -785,8 +783,8 @@ class TestShipsanityCrops(SVTestBase):
} }
def test_only_crop_shipsanity_locations(self): def test_only_crop_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags)
@ -808,8 +806,8 @@ class TestShipsanityCropsExcludeIsland(SVTestBase):
} }
def test_only_crop_shipsanity_locations(self): def test_only_crop_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags)
@ -831,8 +829,8 @@ class TestShipsanityCropsNoQiCropWithoutSpecialOrders(SVTestBase):
} }
def test_only_crop_shipsanity_locations(self): def test_only_crop_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags)
@ -854,8 +852,8 @@ class TestShipsanityFish(SVTestBase):
} }
def test_only_fish_shipsanity_locations(self): def test_only_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -878,8 +876,8 @@ class TestShipsanityFishExcludeIsland(SVTestBase):
} }
def test_only_fish_shipsanity_locations(self): def test_only_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -902,8 +900,8 @@ class TestShipsanityFishExcludeQiOrders(SVTestBase):
} }
def test_only_fish_shipsanity_locations(self): def test_only_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -926,8 +924,8 @@ class TestShipsanityFullShipment(SVTestBase):
} }
def test_only_full_shipment_shipsanity_locations(self): def test_only_full_shipment_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags)
self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -953,8 +951,8 @@ class TestShipsanityFullShipmentExcludeIsland(SVTestBase):
} }
def test_only_full_shipment_shipsanity_locations(self): def test_only_full_shipment_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags)
self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -979,8 +977,8 @@ class TestShipsanityFullShipmentExcludeQiBoard(SVTestBase):
} }
def test_only_full_shipment_shipsanity_locations(self): def test_only_full_shipment_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags)
self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -1006,8 +1004,8 @@ class TestShipsanityFullShipmentWithFish(SVTestBase):
} }
def test_only_full_shipment_and_fish_shipsanity_locations(self): def test_only_full_shipment_and_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or
LocationTags.SHIPSANITY_FISH in location_table[location.name].tags) LocationTags.SHIPSANITY_FISH in location_table[location.name].tags)
@ -1041,8 +1039,8 @@ class TestShipsanityFullShipmentWithFishExcludeIsland(SVTestBase):
} }
def test_only_full_shipment_and_fish_shipsanity_locations(self): def test_only_full_shipment_and_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or
LocationTags.SHIPSANITY_FISH in location_table[location.name].tags) LocationTags.SHIPSANITY_FISH in location_table[location.name].tags)
@ -1075,8 +1073,8 @@ class TestShipsanityFullShipmentWithFishExcludeQiBoard(SVTestBase):
} }
def test_only_full_shipment_and_fish_shipsanity_locations(self): def test_only_full_shipment_and_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
with self.subTest(location.name): with self.subTest(location.name):
self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or
LocationTags.SHIPSANITY_FISH in location_table[location.name].tags) LocationTags.SHIPSANITY_FISH in location_table[location.name].tags)

View File

@ -557,8 +557,8 @@ class TestDonationLogicRandomized(SVTestBase):
railroad_item = "Railroad Boulder Removed" railroad_item = "Railroad Boulder Removed"
swap_museum_and_bathhouse(self.multiworld, self.player) swap_museum_and_bathhouse(self.multiworld, self.player)
collect_all_except(self.multiworld, railroad_item) collect_all_except(self.multiworld, railroad_item)
donation_locations = [location for location in self.multiworld.get_locations() if donation_locations = [location for location in self.get_real_locations() if
not location.event and LocationTags.MUSEUM_DONATIONS in location_table[location.name].tags] LocationTags.MUSEUM_DONATIONS in location_table[location.name].tags]
for donation in donation_locations: for donation in donation_locations:
self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state)) self.assertFalse(self.world.logic.region.can_reach_location(donation.name)(self.multiworld.state))
@ -713,10 +713,9 @@ class TestShipsanityNone(SVTestBase):
} }
def test_no_shipsanity_locations(self): def test_no_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event: self.assertFalse("Shipsanity" in location.name)
self.assertFalse("Shipsanity" in location.name) self.assertNotIn(LocationTags.SHIPSANITY, location_table[location.name].tags)
self.assertNotIn(LocationTags.SHIPSANITY, location_table[location.name].tags)
class TestShipsanityCrops(SVTestBase): class TestShipsanityCrops(SVTestBase):
@ -725,8 +724,8 @@ class TestShipsanityCrops(SVTestBase):
} }
def test_only_crop_shipsanity_locations(self): def test_only_crop_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_CROP, location_table[location.name].tags)
@ -736,8 +735,8 @@ class TestShipsanityFish(SVTestBase):
} }
def test_only_fish_shipsanity_locations(self): def test_only_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -747,8 +746,8 @@ class TestShipsanityFullShipment(SVTestBase):
} }
def test_only_full_shipment_shipsanity_locations(self): def test_only_full_shipment_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags) self.assertIn(LocationTags.SHIPSANITY_FULL_SHIPMENT, location_table[location.name].tags)
self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags) self.assertNotIn(LocationTags.SHIPSANITY_FISH, location_table[location.name].tags)
@ -759,8 +758,8 @@ class TestShipsanityFullShipmentWithFish(SVTestBase):
} }
def test_only_full_shipment_and_fish_shipsanity_locations(self): def test_only_full_shipment_and_fish_shipsanity_locations(self):
for location in self.multiworld.get_locations(self.player): for location in self.get_real_locations():
if not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags: if LocationTags.SHIPSANITY in location_table[location.name].tags:
self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or self.assertTrue(LocationTags.SHIPSANITY_FULL_SHIPMENT in location_table[location.name].tags or
LocationTags.SHIPSANITY_FISH in location_table[location.name].tags) LocationTags.SHIPSANITY_FISH in location_table[location.name].tags)
@ -774,8 +773,8 @@ class TestShipsanityEverything(SVTestBase):
def test_all_shipsanity_locations_require_shipping_bin(self): def test_all_shipsanity_locations_require_shipping_bin(self):
bin_name = "Shipping Bin" bin_name = "Shipping Bin"
collect_all_except(self.multiworld, bin_name) collect_all_except(self.multiworld, bin_name)
shipsanity_locations = [location for location in self.multiworld.get_locations() if shipsanity_locations = [location for location in self.get_real_locations() if
not location.event and LocationTags.SHIPSANITY in location_table[location.name].tags] LocationTags.SHIPSANITY in location_table[location.name].tags]
bin_item = self.world.create_item(bin_name) bin_item = self.world.create_item(bin_name)
for location in shipsanity_locations: for location in shipsanity_locations:
with self.subTest(location.name): with self.subTest(location.name):

View File

@ -277,10 +277,10 @@ class SVTestBase(RuleAssertMixin, WorldTestBase, SVTestCase):
self.multiworld.state.collect(self.world.create_item("Stardrop"), event=False) self.multiworld.state.collect(self.world.create_item("Stardrop"), event=False)
def get_real_locations(self) -> List[Location]: def get_real_locations(self) -> List[Location]:
return [location for location in self.multiworld.get_locations(self.player) if not location.event] return [location for location in self.multiworld.get_locations(self.player) if location.address is not None]
def get_real_location_names(self) -> List[str]: def get_real_location_names(self) -> List[str]:
return [location.name for location in self.multiworld.get_locations(self.player) if not location.event] return [location.name for location in self.get_real_locations()]
pre_generated_worlds = {} pre_generated_worlds = {}

View File

@ -20,7 +20,7 @@ class ModAssertMixin(TestCase):
self.assertTrue(item.mod_name is None or item.mod_name in chosen_mods, self.assertTrue(item.mod_name is None or item.mod_name in chosen_mods,
f"Item {item.name} has is from mod {item.mod_name}. Allowed mods are {chosen_mods}.") f"Item {item.name} has is from mod {item.mod_name}. Allowed mods are {chosen_mods}.")
for multiworld_location in multiworld.get_locations(): for multiworld_location in multiworld.get_locations():
if multiworld_location.event: if multiworld_location.address is None:
continue continue
location = location_table[multiworld_location.name] location = location_table[multiworld_location.name]
self.assertTrue(location.mod_name is None or location.mod_name in chosen_mods) self.assertTrue(location.mod_name is None or location.mod_name in chosen_mods)

View File

@ -13,7 +13,7 @@ def get_all_item_names(multiworld: MultiWorld) -> List[str]:
def get_all_location_names(multiworld: MultiWorld) -> List[str]: def get_all_location_names(multiworld: MultiWorld) -> List[str]:
return [location.name for location in multiworld.get_locations() if not location.event] return [location.name for location in multiworld.get_locations() if location.address is not None]
class WorldAssertMixin(RuleAssertMixin, TestCase): class WorldAssertMixin(RuleAssertMixin, TestCase):
@ -48,7 +48,7 @@ class WorldAssertMixin(RuleAssertMixin, TestCase):
self.assert_can_reach_victory(multiworld) self.assert_can_reach_victory(multiworld)
def assert_same_number_items_locations(self, multiworld: MultiWorld): def assert_same_number_items_locations(self, multiworld: MultiWorld):
non_event_locations = [location for location in multiworld.get_locations() if not location.event] non_event_locations = [location for location in multiworld.get_locations() if location.address is not None]
self.assertEqual(len(multiworld.itempool), len(non_event_locations)) self.assertEqual(len(multiworld.itempool), len(non_event_locations))
def assert_can_reach_everything(self, multiworld: MultiWorld): def assert_can_reach_everything(self, multiworld: MultiWorld):

View File

@ -206,7 +206,6 @@ def create_location(player: int, location_data: LocationData, region: Region) ->
location.access_rule = location_data.rule location.access_rule = location_data.rule
if id is None: if id is None:
location.event = True
location.locked = True location.locked = True
return location return location

View File

@ -116,7 +116,6 @@ class TLoZWorld(World):
def create_location(self, name, id, parent, event=False): def create_location(self, name, id, parent, event=False):
return_location = TLoZLocation(self.player, name, id, parent) return_location = TLoZLocation(self.player, name, id, parent)
return_location.event = event
return return_location return return_location
def create_regions(self): def create_regions(self):

View File

@ -10,10 +10,6 @@ class AdvData(typing.NamedTuple):
class UndertaleAdvancement(Location): class UndertaleAdvancement(Location):
game: str = "Undertale" game: str = "Undertale"
def __init__(self, player: int, name: str, address: typing.Optional[int], parent):
super().__init__(player, name, address, parent)
self.event = not address
advancement_table = { advancement_table = {
"Snowman": AdvData(79100, "Snowdin Forest"), "Snowman": AdvData(79100, "Snowdin Forest"),

View File

@ -131,12 +131,6 @@ def create_region(world: MultiWorld, player: int, name: str, locations=None, exi
class WargrooveLocation(Location): class WargrooveLocation(Location):
game: str = "Wargroove" game: str = "Wargroove"
def __init__(self, player: int, name: str, address=None, parent=None):
super(WargrooveLocation, self).__init__(player, name, address, parent)
if address is None:
self.event = True
self.locked = True
class WargrooveItem(Item): class WargrooveItem(Item):
game = "Wargroove" game = "Wargroove"

View File

@ -109,9 +109,7 @@ class ZorkGrandInquisitorWorld(World):
region_mapping[data.region], region_mapping[data.region],
) )
location.event = isinstance(location_enum_item, ZorkGrandInquisitorEvents) if isinstance(location_enum_item, ZorkGrandInquisitorEvents):
if location.event:
location.place_locked_item( location.place_locked_item(
ZorkGrandInquisitorItem( ZorkGrandInquisitorItem(
data.event_item_name, data.event_item_name,