fix(key logic): typo

fix(bunny logic): multiple paths considered
This commit is contained in:
aerinon
2023-11-13 15:43:27 -07:00
parent fd99620ac9
commit 71eadd051c
4 changed files with 100 additions and 85 deletions

View File

@@ -1800,7 +1800,7 @@ def imp_locations_factory(world, player):
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
if world.mode[player] == 'standard':
imp_locations.append('Zelda Pickup')
imp_locations.append('Zelda Dropoff')
imp_locations.append('Zelda Drop Off')
return imp_locations

View File

@@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
from source.tools.BPS import create_bps_from_data
from source.classes.CustomSettings import CustomSettings
version_number = '1.2.0.21'
version_number = '1.2.0.22'
version_branch = '-u'
__version__ = f'{version_number}{version_branch}'

View File

@@ -109,6 +109,10 @@ These are now independent of retro mode and have three options: None, Random, an
# Bug Fixes and Notes
* * 1.2.0.22u
* Fixed logic issues:
* Self-locking key not allowed in Sanctuary in standard (typo fixed)
* More advanced bunny-walking logic in dungeons (multiple paths considred)
* 1.2.0.21u
* Fix that should force items needed for leaving Zelda's cell to before the throne room, so S&Q isn't mandatory
* Small fix for Tavern Shuffle (thanks Catobat)

View File

@@ -101,16 +101,20 @@ def mirrorless_path_to_castle_courtyard(world, player):
else:
queue.append((entrance.connected_region, new_path))
def set_rule(spot, rule):
spot.access_rule = rule
def set_defeat_dungeon_boss_rule(location):
# Lambda required to defer evaluation of dungeon.boss since it will change later if boos shuffle is used
set_rule(location, lambda state: location.parent_region.dungeon.boss.can_defeat(state))
def set_always_allow(spot, rule):
spot.always_allow = rule
def add_rule(spot, rule, combine='and'):
old_rule = spot.access_rule
if combine == 'or':
@@ -140,22 +144,26 @@ def forbid_item(location, item, player):
old_rule = location.item_rule
location.item_rule = lambda i: (i.name != item or i.player != player) and old_rule(i)
def add_item_rule(location, rule):
old_rule = location.item_rule
location.item_rule = lambda item: rule(item) and old_rule(item)
def item_in_locations(state, item, player, locations):
for location in locations:
if item_name(state, location[0], location[1]) == (item, player):
return True
return False
def item_name(state, location, player):
location = state.world.get_location(location, player)
if location.item is None:
return None
return (location.item.name, location.item.player)
def global_rules(world, player):
# ganon can only carry triforce
add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)
@@ -1109,17 +1117,20 @@ def forbid_bomb_jump_requirements(world, player):
set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False)
set_rule(world.get_entrance('Ice Island To East Pier', player), lambda state: False)
# Light cones in standard depend on which world we actually are in, not which one the location would normally be
# We add Lamp requirements only to those locations which lie in the dark world (or everything if open
DW_Entrances = ['Bumper Cave (Bottom)', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', 'Dark Death Mountain Ledge (East)',
'Turtle Rock Isolated Ledge Entrance', 'Thieves Town', 'Skull Woods Final Section', 'Ice Palace', 'Misery Mire', 'Palace of Darkness', 'Swamp Palace', 'Turtle Rock', 'Dark Death Mountain Ledge (West)']
def check_is_dark_world(region):
for entrance in region.entrances:
if entrance.name in DW_Entrances:
return True
return False
def add_conditional_lamps(world, player):
def add_conditional_lamp(spot, region, spottype='Location'):
if spottype == 'Location':
@@ -1262,6 +1273,7 @@ std_kill_doors_if_trapped = {
# 'Ice Lobby S' # can melt rule is sufficient
}
def add_connection(parent_name, target_name, entrance_name, world, player):
parent = world.get_region(parent_name, player)
target = world.get_region(target_name, player)
@@ -1326,6 +1338,7 @@ def standard_rules(world, player):
def check_rule_list(state, r_list):
return True if len(r_list) <= 0 else r_list[0](state) and check_rule_list(state, r_list[1:])
rule_list, debug_path = find_rules_for_zelda_delivery(world, player)
set_rule(world.get_entrance('Hyrule Castle Throne Room Tapestry', player),
lambda state: state.has('Zelda Herself', player) and check_rule_list(state, rule_list))
@@ -1809,7 +1822,6 @@ def set_inverted_big_bomb_rules(world, player):
def set_bunny_rules(world, player, inverted):
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing.
bunny_impassable_caves = ['Bumper Cave (top)', 'Bumper Cave (bottom)', 'Two Brothers House',
@@ -1848,6 +1860,7 @@ def set_bunny_rules(world, player, inverted):
return region.is_light_world
else:
return region.is_dark_world
def is_link(region):
if inverted:
return region.is_dark_world
@@ -1877,16 +1890,15 @@ def set_bunny_rules(world, player, inverted):
# for each such entrance a new option is added that consist of:
# a) being able to reach it, and
# b) being able to access all entrances from there to `region`
seen = {region}
queue = deque([(region, [])])
queue = deque([(region, [], {region})])
while queue:
(current, path) = queue.popleft()
(current, path, seen) = queue.popleft()
for entrance in current.entrances:
new_region = entrance.parent_region
if new_region.type in (RegionType.Cave, RegionType.Dungeon) and new_region in seen:
continue
new_path = path + [entrance.access_rule]
seen.add(new_region)
new_seen = seen.union({new_region})
if not is_link(new_region):
if world.logic[player] == 'owglitches':
if region.type == RegionType.Dungeon and new_region.type != RegionType.Dungeon:
@@ -1923,7 +1935,7 @@ def set_bunny_rules(world, player, inverted):
else:
continue
if is_bunny(new_region):
queue.append((new_region, new_path))
queue.append((new_region, new_path, new_seen))
else:
# we have reached pure light world, so we have a new possible option
possible_options.append(path_to_access_rule(new_path, entrance))
@@ -1975,7 +1987,6 @@ drop_dungeon_entrances = {
"Skull Back Drop"
}
bunny_revivable_entrances = {
"Sewers Pull Switch", "TR Dash Room", "Swamp Boss", "Hera Boss",
"Tower Agahnim 1", "Ice Lobby", "Sewers Rat Path", "PoD Falling Bridge",