Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: replace Location.event with advancement property #2871

Merged
merged 9 commits into from
Apr 14, 2024
13 changes: 7 additions & 6 deletions BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,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 @@ -593,8 +593,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):
Comment on lines 586 to +587
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is how I would format this:

            if location.progress_type != LocationProgressType.EXCLUDED and (
                location.player in players["locations"] or location.advancement
            ):

Not saying this is better, just presenting another option in case you were looking for one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd rather leave it how it is due to it being the current style in AP and I don't think we ever decided on which one we should use going forward.

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 native_item(self) -> bool:
"""Returns True if the item in this location matches game."""
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 @@ -298,7 +297,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 @@ -643,7 +641,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 @@ -700,7 +698,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 @@ -731,7 +729,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 @@ -752,7 +750,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 @@ -949,7 +946,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
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 @@ -81,7 +81,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 @@ -490,7 +489,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 @@ -528,13 +526,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 @@ -747,7 +745,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, ItemFactory('Triforce', player), 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 = ItemFactory(event_name, player)
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 @@ -1184,7 +1184,6 @@ def tr_big_key_chest_keys_needed(state):
item = ItemFactory('Small Key (Turtle Rock)', 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
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
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.advancement and loc.locked and loc not in reachable]
alwaysintreble marked this conversation as resolved.
Show resolved Hide resolved
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
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 @@ -1524,7 +1524,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
2 changes: 0 additions & 2 deletions worlds/sc2wol/Regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ def build_connection_rule(mission_names: List[str], missions_req: int) -> Callab
for i in range(len(location_cache) - 1, -1, -1):
if location_cache[i].name == final_location:
location_cache[i].locked = True
location_cache[i].event = True
location_cache[i].address = None
break
else:
Expand All @@ -263,7 +262,6 @@ def create_location(player: int, location_data: LocationData, region: Region,
location.access_rule = location_data.rule

if id is None:
location.event = True
location.locked = True

location_cache.append(location)
Expand Down
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
2 changes: 1 addition & 1 deletion worlds/stardew_valley/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def create_items(self):

locations_count = len([location
for location in self.multiworld.get_locations(self.player)
if not location.event])
if not location.advancement])
alwaysintreble marked this conversation as resolved.
Show resolved Hide resolved

created_items = create_items(self.create_item, locations_count, items_to_exclude, self.options,
self.multiworld.random)
Expand Down
10 changes: 5 additions & 5 deletions worlds/stardew_valley/test/TestGeneration.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@


def get_real_locations(tester: typing.Union[SVTestBase, SVTestCase], multiworld: MultiWorld):
return [location for location in multiworld.get_locations(tester.player) if not location.event]
return [location for location in multiworld.get_locations(tester.player) if not location.advancement]


def get_real_location_names(tester: typing.Union[SVTestBase, SVTestCase], multiworld: MultiWorld):
return [location.name for location in multiworld.get_locations(tester.player) if not location.event]
return [location.name for location in multiworld.get_locations(tester.player) if not location.advancement]


class TestBaseItemGeneration(SVTestBase):
Expand Down Expand Up @@ -43,7 +43,7 @@ def test_all_progression_items_are_added_to_the_pool(self):

def test_creates_as_many_item_as_non_event_locations(self):
non_event_locations = [location for location in get_real_locations(self, self.multiworld) if
not location.event]
not location.advancement]

self.assertEqual(len(non_event_locations), len(self.multiworld.itempool))

Expand Down Expand Up @@ -94,7 +94,7 @@ def test_all_progression_items_except_island_are_added_to_the_pool(self):

def test_creates_as_many_item_as_non_event_locations(self):
non_event_locations = [location for location in get_real_locations(self, self.multiworld) if
not location.event]
not location.advancement]

self.assertEqual(len(non_event_locations), len(self.multiworld.itempool))

Expand Down Expand Up @@ -189,7 +189,7 @@ class TestLocationGeneration(SVTestBase):

def test_all_location_created_are_in_location_table(self):
for location in get_real_locations(self, self.multiworld):
if not location.event:
if not location.advancement:
self.assertIn(location.name, location_table)


Expand Down
Loading
Loading