Skip to content

Commit

Permalink
Core: replace Location.event with advancement property (Archipela…
Browse files Browse the repository at this point in the history
  • Loading branch information
alwaysintreble authored and EmilyV99 committed Apr 15, 2024
1 parent 23d2d7d commit 6a15860
Show file tree
Hide file tree
Showing 35 changed files with 78 additions and 143 deletions.
13 changes: 7 additions & 6 deletions BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def push_item(self, location: Location, item: Item, collect: bool = True):
location.item = item
item.location = location
if collect:
self.state.collect(item, location.event, location)
self.state.collect(item, location.advancement, location)

logging.debug('Placed %s at %s', item, location)

Expand Down Expand Up @@ -584,8 +584,7 @@ def location_condition(location: Location):
def location_relevant(location: Location):
"""Determine if this location is relevant to sweep."""
if location.progress_type != LocationProgressType.EXCLUDED \
and (location.player in players["locations"] or location.event
or (location.item and location.item.advancement)):
and (location.player in players["locations"] or location.advancement):
return True
return False

Expand Down Expand Up @@ -730,7 +729,7 @@ def sweep_for_events(self, key_only: bool = False, locations: Optional[Iterable[
locations = self.multiworld.get_filled_locations()
reachable_events = True
# 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)}
while reachable_events:
reachable_events = {location for location in locations if location.can_reach(self)}
Expand Down Expand Up @@ -1020,7 +1019,6 @@ class Location:
name: str
address: Optional[int]
parent_region: Optional[Region]
event: bool = False
locked: bool = False
show_in_spoiler: bool = True
progress_type: LocationProgressType = LocationProgressType.DEFAULT
Expand Down Expand Up @@ -1051,7 +1049,6 @@ def place_locked_item(self, item: Item):
raise Exception(f"Location {self} already filled.")
self.item = item
item.location = self
self.event = item.advancement
self.locked = True

def __repr__(self):
Expand All @@ -1067,6 +1064,10 @@ def __hash__(self):
def __lt__(self, other: Location):
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
def is_event(self) -> bool:
"""Returns True if the address of this location is None, denoting it is an Event Location."""
Expand Down
10 changes: 3 additions & 7 deletions Fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
multiworld.push_item(spot_to_fill, item_to_place, False)
spot_to_fill.locked = lock
placements.append(spot_to_fill)
spot_to_fill.event = item_to_place.advancement
placed += 1
if not placed % 1000:
_log_fill_progress(name, placed, total)
Expand Down Expand Up @@ -310,7 +309,6 @@ def accessibility_corrections(multiworld: MultiWorld, state: CollectionState, lo
pool.append(location.item)
state.remove(location.item)
location.item = None
location.event = False
if location in state.events:
state.events.remove(location)
locations.append(location)
Expand Down Expand Up @@ -659,7 +657,7 @@ def item_percentage(player: int, num: int) -> float:
while True:
# Check locations in the current sphere and gather progression items to swap earlier
for location in balancing_sphere:
if location.event:
if location.advancement:
balancing_state.collect(location.item, True, location)
player = location.item.player
# only replace items that end up in another player's world
Expand Down Expand Up @@ -716,7 +714,7 @@ def item_percentage(player: int, num: int) -> float:

# sort then shuffle to maintain deterministic behaviour,
# 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)
items_to_replace.sort()
multiworld.random.shuffle(items_to_replace)
Expand Down Expand Up @@ -747,7 +745,7 @@ def item_percentage(player: int, num: int) -> float:
sphere_locations.add(location)

for location in sphere_locations:
if location.event:
if location.advancement:
state.collect(location.item, True, location)
checked_locations |= sphere_locations

Expand All @@ -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_1.item.location = location_1
location_2.item.location = location_2
location_1.event, location_2.event = location_2.event, location_1.event


def distribute_planned(multiworld: MultiWorld) -> None:
Expand Down Expand Up @@ -965,7 +962,6 @@ def failed(warning: str, force: typing.Union[bool, str]) -> None:
placement['force'])
for (item, location) in successful_pairs:
multiworld.push_item(location, item, collect=False)
location.event = True # flag location to be checked during fill
location.locked = True
logging.debug(f"Plando placed {item} at {location}")
if from_pool:
Expand Down
5 changes: 0 additions & 5 deletions docs/world api.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,6 @@ from BaseClasses import Location

class MyGameLocation(Location):
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`.
Expand Down
2 changes: 1 addition & 1 deletion test/bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def remove(self, items: typing.Union[Item, typing.Iterable[Item]]) -> None:
if isinstance(items, Item):
items = (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.remove(item)

Expand Down
12 changes: 5 additions & 7 deletions test/general/test_fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def fill_region(multiworld: MultiWorld, region: Region, items: List[Item]) -> Li
return items
item = items.pop(0)
multiworld.push_item(location, item, False)
location.event = item.advancement

return items

Expand Down Expand Up @@ -489,7 +488,6 @@ def test_double_sweep(self):
player1 = generate_player_data(multiworld, 1, 1, 1)
location = player1.locations[0]
location.address = None
location.event = True
item = player1.prog_items[0]
item.code = None
location.place_locked_item(item)
Expand Down Expand Up @@ -527,13 +525,13 @@ def test_basic_distribute(self):
distribute_items_restrictive(multiworld)

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.assertTrue(locations[1].event)
self.assertTrue(locations[1].advancement)
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.assertFalse(locations[3].event)
self.assertFalse(locations[3].advancement)

def test_excluded_distribute(self):
"""Test that distribute_items_restrictive doesn't put advancement items on excluded locations"""
Expand Down Expand Up @@ -746,7 +744,7 @@ def test_non_excluded_local_items(self):

for item in multiworld.get_items():
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:
"""Test that the early items API successfully places items early"""
Expand Down
4 changes: 1 addition & 3 deletions worlds/alttp/ItemPool.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,8 @@ def generate_itempool(world):
region.locations.append(loc)

multiworld.push_item(loc, item_factory('Triforce', world), False)
loc.event = True
loc.locked = True

multiworld.get_location('Ganon', player).event = True
multiworld.get_location('Ganon', player).locked = True
event_pairs = [
('Agahnim 1', 'Beat Agahnim 1'),
Expand All @@ -273,7 +271,7 @@ def generate_itempool(world):
location = multiworld.get_location(location_name, player)
event = item_factory(event_name, world)
multiworld.push_item(location, event, False)
location.event = location.locked = True
location.locked = True


# set up item pool
Expand Down
1 change: 0 additions & 1 deletion worlds/alttp/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,6 @@ def tr_big_key_chest_keys_needed(state):
item = item_factory('Small Key (Turtle Rock)', world.worlds[player])
location = world.get_location('Turtle Rock - Big Key Chest', player)
location.place_locked_item(item)
location.event = True
toss_junk_item(world, player)

if world.accessibility[player] != 'locations':
Expand Down
4 changes: 0 additions & 4 deletions worlds/checksfinder/Locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ class AdvData(typing.NamedTuple):
class ChecksFinderAdvancement(Location):
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 = {
"Tile 1": AdvData(81000, 'Board'),
Expand Down
2 changes: 1 addition & 1 deletion worlds/dlcquest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def create_items(self):
self.precollect_coinsanity()
locations_count = len([location
for location in self.multiworld.get_locations(self.player)
if not location.event])
if not location.advancement])

items_to_exclude = [excluded_items
for excluded_items in self.multiworld.precollected_items[self.player]]
Expand Down
4 changes: 2 additions & 2 deletions worlds/dlcquest/test/checks/world_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def get_all_item_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):
Expand Down Expand Up @@ -38,5 +38,5 @@ def assert_can_win(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))
2 changes: 1 addition & 1 deletion worlds/generic/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
raise Exception(f"Unable to exclude location {loc_name} in player {player}'s world.") from e
else:
if not location.event:
if not location.advancement:
location.progress_type = LocationProgressType.EXCLUDED
else:
logging.warning(f"Unable to exclude location {loc_name} in player {player}'s world.")
Expand Down
8 changes: 3 additions & 5 deletions worlds/ladx/Locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,11 @@ class LinksAwakeningLocation(Location):

def __init__(self, player: int, region, ladxr_item):
name = meta_to_name(ladxr_item.metadata)
address = None

self.event = ladxr_item.event is not None
if self.event:
if ladxr_item.event is not None:
name = ladxr_item.event

address = None
if not self.event:
else:
address = locations_to_id[name]
super().__init__(player, name, address)
self.parent_region = region
Expand Down
2 changes: 1 addition & 1 deletion worlds/ladx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def create_regions(self) -> None:
# Place RAFT, other access events
for region in regions:
for loc in region.locations:
if loc.event:
if loc.address is None:
loc.place_locked_item(self.create_event(loc.ladxr_item.event))

# Connect Windfish -> Victory
Expand Down
5 changes: 0 additions & 5 deletions worlds/meritous/Locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
class MeritousLocation(Location):
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

Expand Down
5 changes: 1 addition & 4 deletions worlds/oot/Location.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,11 @@ def __init__(self, player, name='', code=None, address1=None, address2=None,
self.vanilla_item = vanilla_item
if filter_tags is None:
self.filter_tags = None
else:
else:
self.filter_tags = list(filter_tags)
self.never = False # no idea what this does
self.disabled = DisableType.ENABLED

if type == 'Event':
self.event = True

@property
def dungeon(self):
return self.parent_region.dungeon
Expand Down
4 changes: 1 addition & 3 deletions worlds/oot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,6 @@ def make_event_item(self, name, location, item=None):
item = self.create_item(name, allow_arbitrary_name=True)
self.multiworld.push_item(location, item, collect=False)
location.locked = True
location.event = True
if name not in item_table:
location.internal = True
return item
Expand Down Expand Up @@ -842,7 +841,7 @@ def generate_basic(self): # mostly killing locations that shouldn't exist by se
all_state.sweep_for_events(locations=all_locations)
reachable = self.multiworld.get_reachable_locations(all_state, self.player)
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:
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.
Expand Down Expand Up @@ -972,7 +971,6 @@ def prefill_state(base_state):
for location in song_locations:
location.item = None
location.locked = False
location.event = False
else:
break

Expand Down
2 changes: 0 additions & 2 deletions worlds/overcooked2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ def add_level_location(
region,
)

location.event = is_event

if priority:
location.progress_type = LocationProgressType.PRIORITY
else:
Expand Down
1 change: 0 additions & 1 deletion worlds/pokemon_rb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ def stage_fill_hook(cls, multiworld, progitempool, usefulitempool, filleritempoo
state = sweep_from_pool(multiworld.state, progitempool + unplaced_items)
if (not item.advancement) or state.can_reach(loc, "Location", loc.player):
multiworld.push_item(loc, item, False)
loc.event = item.advancement
fill_locations.remove(loc)
break
else:
Expand Down
2 changes: 0 additions & 2 deletions worlds/pokemon_rb/encounters.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ def process_pokemon_locations(self):
mon = randomize_pokemon(self, original_mon, mons_list, 2, self.multiworld.random)
placed_mons[mon] += 1
location.item = self.create_item(mon)
location.event = True
location.locked = True
location.item.location = location
locations.append(location)
Expand Down Expand Up @@ -269,7 +268,6 @@ def process_pokemon_locations(self):
for slot in encounter_slots:
location = self.multiworld.get_location(slot.name, self.player)
location.item = self.create_item(slot.original_item)
location.event = True
location.locked = True
location.item.location = location
placed_mons[location.item.name] += 1
1 change: 0 additions & 1 deletion worlds/pokemon_rb/regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,6 @@ def create_regions(self):
item = self.create_filler()
elif location.original_item == "Pokedex":
if self.multiworld.randomize_pokedex[self.player] == "vanilla":
location_object.event = True
event = True
item = self.create_item("Pokedex")
elif location.original_item == "Moon Stone" and self.multiworld.stonesanity[self.player]:
Expand Down
Empty file added worlds/sc2wol/Regions.py
Empty file.
2 changes: 0 additions & 2 deletions worlds/smz3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,6 @@ def post_fill(self):
if (loc.item.player == self.player and loc.always_allow(state, loc.item)):
loc.item.classification = ItemClassification.filler
loc.item.item.Progression = False
loc.item.location.event = False
self.unreachable.append(loc)

def get_filler_item_name(self) -> str:
Expand Down Expand Up @@ -573,7 +572,6 @@ def JunkFillGT(self, factor):
break
assert itemFromPool is not None, "Can't find anymore item(s) to pre fill GT"
self.multiworld.push_item(loc, itemFromPool, False)
loc.event = False
toRemove.sort(reverse = True)
for i in toRemove:
self.multiworld.itempool.pop(i)
Expand Down
1 change: 0 additions & 1 deletion worlds/soe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,3 @@ def __init__(self, player: int, name: str, address: typing.Optional[int], parent
super().__init__(player, name, address, parent)
# unconditional assignments favor a split dict, saving memory
self.progress_type = LocationProgressType.EXCLUDED if exclude else LocationProgressType.DEFAULT
self.event = not address
Loading

0 comments on commit 6a15860

Please sign in to comment.