Merged in DR v1.2.0.22

This commit is contained in:
codemann8
2023-11-18 17:49:41 -06:00
5 changed files with 94 additions and 76 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

@@ -36,7 +36,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,13 @@ These are now independent of retro mode and have three options: None, Random, an
# Bug Fixes and Notes
* 1.2.0.22u
* Flute can't be activated in rain state (except glitched modes) (Thanks codemann!)
* ER: Minor fix for Link's House on DM in Insanity (escape cave should not be re-used)
* Logic issues:
* Self-locking key not allowed in Sanctuary in standard (typo fixed)
* More advanced bunny-walking logic in dungeons (multiple paths considred)
* MSU: GTBK song fix for DR (Thanks codemann!)
* 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

@@ -128,9 +128,11 @@ def mirrorless_path_to_castle_courtyard(world, player):
queue.append((entrance.connected_region, new_path))
seen.add(entrance.connected_region)
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))
@@ -139,6 +141,7 @@ def set_defeat_dungeon_boss_rule(location):
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':
@@ -167,22 +170,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)
@@ -1378,6 +1385,7 @@ 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 Lake Iceberg Bomb Jump', player), lambda state: False)
def add_conditional_lamps(world, player):
def add_conditional_lamp(spot, spottype='Location'):
if spottype == 'Location':
@@ -1519,6 +1527,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)
@@ -1581,6 +1590,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))
@@ -1619,16 +1629,15 @@ def find_rules_for_zelda_delivery(world, player):
if not rule(blank_state):
rule_list.append(rule)
next_path.append(ext.name)
if connect.name == 'Sanctuary':
if connect.name == 'Hyrule Castle Throne Room':
return rule_list, next_path
else:
visited.add(connect)
queue.append((connect, rule_list, next_path))
raise Exception('No path to Sanctuary found')
raise Exception('No path to Throne Room found')
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',
@@ -1668,6 +1677,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
@@ -1697,16 +1707,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:
@@ -1743,7 +1752,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))
@@ -1795,7 +1804,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",

View File

@@ -711,7 +711,10 @@ def do_links_house(entrances, exits, avail, cross_world):
connect_entrance(chosen_dm_escape, chosen_exit_start, avail)
connect_exit(chosen_exit_end, chosen_landing, avail)
entrances.remove(chosen_dm_escape)
avail.decoupled_exits.remove(chosen_exit_start)
avail.decoupled_entrances.remove(chosen_landing)
# chosen cave has already been removed from exits
exits.add(chosen_exit_start) # this needs to be added back in
if len(chosen_cave):
exits.update([x for x in chosen_cave])
exits.update([x for item in multi_exit_caves for x in item])