Support bunny pocket for SW back and voo hammer house

This commit is contained in:
KrisDavie
2023-12-12 18:48:12 +01:00
parent 6a41dff98b
commit 6510968401
3 changed files with 81 additions and 3 deletions

View File

@@ -550,6 +550,42 @@ class CollectionState(object):
self.placing_items = None self.placing_items = None
# self.trace = None # self.trace = None
def can_reach_from(self, spot, start, player=None):
old_state = self.copy()
# old_state.path = {old_state.world.get_region(start, player)}
old_state.stale[player] = False
old_state.reachable_regions[player] = dict()
old_state.blocked_connections[player] = dict()
rrp = old_state.reachable_regions[player]
bc = old_state.blocked_connections[player]
# init on first call - this can't be done on construction since the regions don't exist yet
start = self.world.get_region(start, player)
if start in self.reachable_regions[player]:
rrp[start] = self.reachable_regions[player][start]
for conn in start.exits:
bc[conn] = self.blocked_connections[player][conn]
else:
rrp[start] = CrystalBarrier.Orange
for conn in start.exits:
bc[conn] = CrystalBarrier.Orange
queue = deque(old_state.blocked_connections[player].items())
old_state.traverse_world(queue, rrp, bc, player)
if old_state.world.key_logic_algorithm[player] == 'default':
unresolved_events = [x for y in old_state.reachable_regions[player] for x in y.locations
if x.event and x.item and (x.item.smallkey or x.item.bigkey or x.item.advancement)
and x not in old_state.locations_checked and x.can_reach(old_state)]
unresolved_events = old_state._do_not_flood_the_keys(unresolved_events)
if len(unresolved_events) == 0:
old_state.check_key_doors_in_dungeons(rrp, player)
if self.world.get_region(spot, player) in rrp:
return True
else:
return False
def update_reachable_regions(self, player): def update_reachable_regions(self, player):
self.stale[player] = False self.stale[player] = False
rrp = self.reachable_regions[player] rrp = self.reachable_regions[player]
@@ -1274,6 +1310,9 @@ class CollectionState(object):
def can_superbunny_mirror_with_sword(self, player): def can_superbunny_mirror_with_sword(self, player):
return self.has_Mirror(player) and self.has_sword(player) return self.has_Mirror(player) and self.has_sword(player)
def can_bunny_pocket(self, player):
return self.has_Boots(player) and (self.has_Mirror(player) or self.has_bottle(player))
def collect(self, item, event=False, location=None): def collect(self, item, event=False, location=None):
if location: if location:

View File

@@ -19,7 +19,6 @@ boots_required_superbunny_mirror_locations = [
# Entrances that can't be superbunny-mirrored into. # Entrances that can't be superbunny-mirrored into.
invalid_mirror_bunny_entrances = [ invalid_mirror_bunny_entrances = [
"Skull Woods Final Section",
"Hype Cave", "Hype Cave",
"Bonk Fairy (Dark)", "Bonk Fairy (Dark)",
"Thieves Town", "Thieves Town",
@@ -107,7 +106,7 @@ inverted_non_mandatory_exits = [
"Hyrule Castle Entrance (East)", "Hyrule Castle Entrance (East)",
] + non_mandatory_exits ] + non_mandatory_exits
open_non_mandatory_exits_ = [ open_non_mandatory_exits = [
"Dark Death Mountain Ledge (West)", "Dark Death Mountain Ledge (West)",
"Dark Death Mountain Ledge (East)", "Dark Death Mountain Ledge (East)",
"Mimic Cave", "Mimic Cave",
@@ -296,7 +295,12 @@ def overworld_glitches_rules(world, player):
# This is doable even with bad enemies # This is doable even with bad enemies
add_alternate_rule(world.get_location("Hobo", player), lambda state: state.can_boots_clip_lw(player)) add_alternate_rule(world.get_location("Hobo", player), lambda state: state.can_boots_clip_lw(player))
# Bunny pocket
if not inverted:
add_alternate_rule(world.get_entrance("Skull Woods Final Section", player), lambda state: state.can_bunny_pocket(player) and state.has("Fire Rod", player))
add_alternate_rule(world.get_entrance("Dark World Shop", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
def add_alternate_rule(entrance, rule): def add_alternate_rule(entrance, rule):

View File

@@ -1902,6 +1902,34 @@ def set_bunny_rules(world, player, inverted):
return region.is_dark_world return region.is_dark_world
else: else:
return region.is_light_world return region.is_light_world
# Is it possible to do bunny pocket here
def can_bunny_pocket_skull_woods(world, player):
# return world.get_entrance(
# "Skull Woods Second Section Door (West)", player
# ).connected_region.type != RegionType.Dungeon and (
# not world.state.can_reach_from("Skull Woods Forest (West)", "Light World", 1)
# or not world.state.can_reach_from("Light World", "Skull Woods Forest (West)", 1)
# )
return world.get_entrance(
"Skull Woods Second Section Door (West)", player
).connected_region.type == RegionType.Dungeon or (
world.state.can_reach_from("Skull Woods Forest (West)", "Light World", 1)
and world.state.can_reach_from("Light World", "Skull Woods Forest (West)", 1)
)
def can_bunny_pocket_voo_shop(world, player):
# return world.get_entrance(
# "Dark World Shop", player
# ).connected_region.type != RegionType.Dungeon and (
# not world.state.can_reach_from("West Dark World", "Light World", 1)
# or not world.state.can_reach_from("Light World", "West Dark World", 1)
# )
return (
world.state.can_reach_from("West Dark World", "Light World", 1)
and world.state.can_reach_from("Light World", "West Dark World", 1)
)
def get_rule_to_add(region, location=None, connecting_entrance=None): def get_rule_to_add(region, location=None, connecting_entrance=None):
# In OWG, a location can potentially be superbunny-mirror accessible or # In OWG, a location can potentially be superbunny-mirror accessible or
@@ -1940,6 +1968,10 @@ def set_bunny_rules(world, player, inverted):
if region.type == RegionType.Dungeon and new_region.type != RegionType.Dungeon: if region.type == RegionType.Dungeon and new_region.type != RegionType.Dungeon:
if entrance.name in OverworldGlitchRules.invalid_mirror_bunny_entrances: if entrance.name in OverworldGlitchRules.invalid_mirror_bunny_entrances:
continue continue
# Is this a bunny pocketable entrance?
if entrance.name == 'Skull Woods Final Section' and not can_bunny_pocket_skull_woods(world, player) or \
entrance.name == 'Dark World Shop' and not can_bunny_pocket_voo_shop(world, player):
continue
if entrance.name in drop_dungeon_entrances: if entrance.name in drop_dungeon_entrances:
lobby = entrance.connected_region lobby = entrance.connected_region
else: else:
@@ -1954,6 +1986,9 @@ def set_bunny_rules(world, player, inverted):
elif region.type == RegionType.Cave and new_region.type != RegionType.Cave: elif region.type == RegionType.Cave and new_region.type != RegionType.Cave:
if entrance.name in OverworldGlitchRules.invalid_mirror_bunny_entrances: if entrance.name in OverworldGlitchRules.invalid_mirror_bunny_entrances:
continue continue
if entrance.name == 'Skull Woods Final Section' and not can_bunny_pocket_skull_woods(world, player) or \
entrance.name == 'Dark World Shop' and not can_bunny_pocket_voo_shop(world, player):
continue
if region.name in OverworldGlitchRules.sword_required_superbunny_mirror_regions: if region.name in OverworldGlitchRules.sword_required_superbunny_mirror_regions:
possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player) and state.has_sword(player)], entrance)) possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player) and state.has_sword(player)], entrance))
elif region.name in OverworldGlitchRules.boots_required_superbunny_mirror_regions: elif region.name in OverworldGlitchRules.boots_required_superbunny_mirror_regions: