mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00
Core: Only consider requested exits during ER placement and speculative sweep #4684
This commit is contained in:
@@ -157,17 +157,16 @@ class ERPlacementState:
|
|||||||
def placed_regions(self) -> set[Region]:
|
def placed_regions(self) -> set[Region]:
|
||||||
return self.collection_state.reachable_regions[self.world.player]
|
return self.collection_state.reachable_regions[self.world.player]
|
||||||
|
|
||||||
def find_placeable_exits(self, check_validity: bool) -> list[Entrance]:
|
def find_placeable_exits(self, check_validity: bool, usable_exits: list[Entrance]) -> list[Entrance]:
|
||||||
if check_validity:
|
if check_validity:
|
||||||
blocked_connections = self.collection_state.blocked_connections[self.world.player]
|
blocked_connections = self.collection_state.blocked_connections[self.world.player]
|
||||||
blocked_connections = sorted(blocked_connections, key=lambda x: x.name)
|
placeable_randomized_exits = [ex for ex in usable_exits
|
||||||
placeable_randomized_exits = [connection for connection in blocked_connections
|
if not ex.connected_region
|
||||||
if not connection.connected_region
|
and ex in blocked_connections
|
||||||
and connection.is_valid_source_transition(self)]
|
and ex.is_valid_source_transition(self)]
|
||||||
else:
|
else:
|
||||||
# this is on a beaten minimal attempt, so any exit anywhere is fair game
|
# this is on a beaten minimal attempt, so any exit anywhere is fair game
|
||||||
placeable_randomized_exits = [ex for region in self.world.multiworld.get_regions(self.world.player)
|
placeable_randomized_exits = [ex for ex in usable_exits if not ex.connected_region]
|
||||||
for ex in region.exits if not ex.connected_region]
|
|
||||||
self.world.random.shuffle(placeable_randomized_exits)
|
self.world.random.shuffle(placeable_randomized_exits)
|
||||||
return placeable_randomized_exits
|
return placeable_randomized_exits
|
||||||
|
|
||||||
@@ -181,7 +180,8 @@ class ERPlacementState:
|
|||||||
self.placements.append(source_exit)
|
self.placements.append(source_exit)
|
||||||
self.pairings.append((source_exit.name, target_entrance.name))
|
self.pairings.append((source_exit.name, target_entrance.name))
|
||||||
|
|
||||||
def test_speculative_connection(self, source_exit: Entrance, target_entrance: Entrance) -> bool:
|
def test_speculative_connection(self, source_exit: Entrance, target_entrance: Entrance,
|
||||||
|
usable_exits: list[Entrance]) -> bool:
|
||||||
copied_state = self.collection_state.copy()
|
copied_state = self.collection_state.copy()
|
||||||
# simulated connection. A real connection is unsafe because the region graph is shallow-copied and would
|
# simulated connection. A real connection is unsafe because the region graph is shallow-copied and would
|
||||||
# propagate back to the real multiworld.
|
# propagate back to the real multiworld.
|
||||||
@@ -198,6 +198,9 @@ class ERPlacementState:
|
|||||||
# ignore the source exit, and, if coupled, the reverse exit. They're not actually new
|
# ignore the source exit, and, if coupled, the reverse exit. They're not actually new
|
||||||
if _exit.name == source_exit.name or (self.coupled and _exit.name == target_entrance.name):
|
if _exit.name == source_exit.name or (self.coupled and _exit.name == target_entrance.name):
|
||||||
continue
|
continue
|
||||||
|
# make sure we are only paying attention to usable exits
|
||||||
|
if _exit not in usable_exits:
|
||||||
|
continue
|
||||||
# technically this should be is_valid_source_transition, but that may rely on side effects from
|
# technically this should be is_valid_source_transition, but that may rely on side effects from
|
||||||
# on_connect, which have not happened here (because we didn't do a real connection, and if we did, we would
|
# on_connect, which have not happened here (because we didn't do a real connection, and if we did, we would
|
||||||
# not want them to persist). can_reach is a close enough approximation most of the time.
|
# not want them to persist). can_reach is a close enough approximation most of the time.
|
||||||
@@ -339,7 +342,7 @@ def randomize_entrances(
|
|||||||
|
|
||||||
def find_pairing(dead_end: bool, require_new_exits: bool) -> bool:
|
def find_pairing(dead_end: bool, require_new_exits: bool) -> bool:
|
||||||
nonlocal perform_validity_check
|
nonlocal perform_validity_check
|
||||||
placeable_exits = er_state.find_placeable_exits(perform_validity_check)
|
placeable_exits = er_state.find_placeable_exits(perform_validity_check, exits)
|
||||||
for source_exit in placeable_exits:
|
for source_exit in placeable_exits:
|
||||||
target_groups = target_group_lookup[source_exit.randomization_group]
|
target_groups = target_group_lookup[source_exit.randomization_group]
|
||||||
for target_entrance in entrance_lookup.get_targets(target_groups, dead_end, preserve_group_order):
|
for target_entrance in entrance_lookup.get_targets(target_groups, dead_end, preserve_group_order):
|
||||||
@@ -355,7 +358,7 @@ def randomize_entrances(
|
|||||||
and len(placeable_exits) == 1)
|
and len(placeable_exits) == 1)
|
||||||
if exit_requirement_satisfied and source_exit.can_connect_to(target_entrance, dead_end, er_state):
|
if exit_requirement_satisfied and source_exit.can_connect_to(target_entrance, dead_end, er_state):
|
||||||
if (needs_speculative_sweep
|
if (needs_speculative_sweep
|
||||||
and not er_state.test_speculative_connection(source_exit, target_entrance)):
|
and not er_state.test_speculative_connection(source_exit, target_entrance, exits)):
|
||||||
continue
|
continue
|
||||||
do_placement(source_exit, target_entrance)
|
do_placement(source_exit, target_entrance)
|
||||||
return True
|
return True
|
||||||
|
Reference in New Issue
Block a user