Fixed OWG logic to apply logic in correct world

This commit is contained in:
codemann8
2022-11-28 14:35:17 -06:00
parent 3ffe137f57
commit 16862b4afd

View File

@@ -142,21 +142,15 @@ def get_boots_clip_exits_lw(world, player):
"""
for name, parent_region, target_region in boots_clips_local:
if not world.is_tile_swapped(OWTileRegions[parent_region], player):
if world.is_tile_lw_like(OWTileRegions[parent_region], player):
yield(name, parent_region, target_region)
for name, parent_region, target_region in boots_clips:
parent_swapped, target_swapped = get_swapped_status(world, player, parent_region, target_region)
if parent_region[0] and not parent_swapped:
if target_region[0] and not target_swapped:
yield(name[0], parent_region[0], target_region[0])
elif target_region[1]:
yield(name[0], parent_region[0], target_region[1])
elif parent_region[1]:
if target_region[0] and not target_swapped:
yield(name[1], parent_region[1], target_region[0])
elif target_region[1]:
yield(name[1], parent_region[1], target_region[1])
for names, parent_regions, target_regions in boots_clips:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions), True)
if region_pair and region_pair[2]:
assert(region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}')
yield(region_pair[0], region_pair[1], region_pair[2])
def get_boots_clip_exits_dw(world, player):
"""
@@ -164,21 +158,14 @@ def get_boots_clip_exits_dw(world, player):
"""
for name, parent_region, target_region in boots_clips_local:
if world.is_tile_swapped(OWTileRegions[parent_region], player):
if not world.is_tile_lw_like(OWTileRegions[parent_region], player):
yield(name, parent_region, target_region)
for name, parent_region, target_region in boots_clips:
parent_swapped, target_swapped = get_swapped_status(world, player, parent_region, target_region)
if parent_region[0] and parent_swapped:
if target_region[0] and target_swapped:
yield(name[0], parent_region[0], target_region[0])
elif target_region[1]:
yield(name[0], parent_region[0], target_region[1])
elif parent_region[1]:
if target_region[0] and target_swapped:
yield(name[1], parent_region[1], target_region[0])
elif target_region[1]:
yield(name[1], parent_region[1], target_region[1])
for names, parent_regions, target_regions in boots_clips:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions), False)
if region_pair and region_pair[2]:
assert(region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}')
yield(region_pair[0], region_pair[1], region_pair[2])
def get_glitched_speed_drops_lw(world, player):
@@ -198,21 +185,14 @@ def get_mirror_clip_spots(world, player):
"""
for name, parent_region, target_region in mirror_clips_local:
if not world.is_tile_swapped(OWTileRegions[parent_region], player):
if not world.is_tile_lw_like(OWTileRegions[parent_region], player):
yield(name, parent_region, target_region)
for name, parent_region, target_region in mirror_clips:
parent_swapped, target_swapped = get_swapped_status(world, player, parent_region, target_region)
if parent_region[0] and not parent_swapped:
if target_region[0] and not target_region:
yield(name[0], parent_region[0], target_region[0])
elif target_region[1]:
yield(name[0], parent_region[0], target_region[1])
elif parent_region[1]:
if target_region[0] and not target_region:
yield(name[1], parent_region[1], target_region[0])
elif target_region[1]:
yield(name[1], parent_region[1], target_region[1])
for names, parent_regions, target_regions in mirror_clips:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions), False)
if region_pair and region_pair[2] and not world.is_tile_lw_like(OWTileRegions[region_pair[1]], player):
assert(region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}')
yield(region_pair[0], region_pair[1], region_pair[2])
def get_mirror_offset_spots(world, player):
@@ -222,19 +202,11 @@ def get_mirror_offset_spots(world, player):
# TODO: These really should check to see if there is a mirrorless path to the mirror portal
# but being that OWG is very very open, it's very unlikely there isn't a path, but possible
for name, parent_region, target_region, path_to in mirror_offsets:
parent_swapped, target_swapped = get_swapped_status(world, player, parent_region, target_region)
if parent_region[0] and not parent_swapped:
if target_region[0] and not target_region:
yield(name[0], parent_region[0], target_region[0])
elif target_region[1]:
yield(name[0], parent_region[0], target_region[1])
elif parent_region[1]:
if target_region[0] and not target_region:
yield(name[1], parent_region[1], target_region[0])
elif target_region[1]:
yield(name[1], parent_region[1], target_region[1])
for names, parent_regions, target_regions, path_to in mirror_offsets:
region_pair = get_world_pair(world, player, get_region_pairs(world, player, names, parent_regions, target_regions, path_to), False)
if region_pair and region_pair[2] and not world.is_tile_lw_like(OWTileRegions[region_pair[1]], player):
assert(region_pair[0], f'Exit name missing in OWG pairing from {region_pair[1]} to {region_pair[2]}')
yield(region_pair[0], region_pair[1], region_pair[2], region_pair[3])
def get_swapped_status(world, player, parents, targets):
@@ -254,6 +226,42 @@ def get_swapped_status(world, player, parents, targets):
return parent_swapped, target_swapped
def get_region_pairs(world, player, names, parent_regions, target_regions, path_regions=None):
# this pairs the source region to the proper destination
region_pairs = [None, None]
parent_swapped, target_swapped = get_swapped_status(world, player, parent_regions, target_regions)
if parent_regions[0]:
region_pairs[0] = [names[0], parent_regions[0]]
if parent_swapped == target_swapped:
region_pairs[0].append(target_regions[0])
if path_regions:
region_pairs[0].append(path_regions[0])
else:
region_pairs[0].append(target_regions[1])
if path_regions:
region_pairs[0][3] = path_regions[1]
if parent_regions[1]:
region_pairs[1] = [names[1], parent_regions[1]]
if parent_swapped == target_swapped:
region_pairs[1].append(target_regions[1])
if path_regions:
region_pairs[1].append(path_regions[1])
else:
region_pairs[1].append(target_regions[0])
if path_regions:
region_pairs[1].append(path_regions[0])
return region_pairs
def get_world_pair(world, player, region_pairs, get_light_world):
# this chooses the region pair that is in the right world
if ((region_pairs[0] and world.is_tile_lw_like(OWTileRegions[region_pairs[0][1]], player)) \
or not world.is_tile_lw_like(OWTileRegions[region_pairs[1][1]], player)) == get_light_world:
return region_pairs[0]
else:
return region_pairs[1]
def create_owg_connections(world, player):
"""
Add OWG transitions to player's world without logic
@@ -267,7 +275,10 @@ def create_owg_connections(world, player):
# Mirror clip spots.
create_no_logic_connections(player, world, get_mirror_clip_spots(world, player))
create_no_logic_connections(player, world, get_mirror_offset_spots(world, player))
# Mirror offset spots.
for data in get_mirror_offset_spots(world, player):
create_no_logic_connections(player, world, [data[0:3]])
def overworld_glitches_rules(world, player):
@@ -281,7 +292,10 @@ def overworld_glitches_rules(world, player):
# Mirror clip spots.
set_owg_rules(player, world, get_mirror_clip_spots(world, player), lambda state: state.has_Mirror(player))
set_owg_rules(player, world, get_mirror_offset_spots(world, player), lambda state: state.has_Mirror(player) and state.can_boots_clip_lw(player))
# Mirror offset spots.
for data in get_mirror_offset_spots(world, player):
set_owg_rules(player, world, [data[0:3]], lambda state: state.has_Mirror(player) and state.can_boots_clip_lw(player) and state.can_reach(data[3], None, player))
# Regions that require the boots and some other stuff.
# TODO: Revisit below when we can guarantee water walk
@@ -297,12 +311,7 @@ def overworld_glitches_rules(world, player):
add_additional_rule(world.get_entrance('VoO To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player))
add_additional_rule(world.get_entrance('Tree Line Water Clip', player), lambda state: state.has('Flippers', player))
add_additional_rule(world.get_entrance('Dark Tree Line Water Clip', player), lambda state: state.has('Flippers', player))
if not world.is_tile_swapped(0x33, player):
add_additional_rule(world.get_entrance('South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player))
world.get_entrance('Dark South Teleporter Cliff Ledge Drop', player).access_rule = lambda state: False
else:
add_additional_rule(world.get_entrance('Dark South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player))
world.get_entrance('South Teleporter Cliff Ledge Drop', player).access_rule = lambda state: False
def add_alternate_rule(entrance, rule):
old_rule = entrance.access_rule
@@ -315,7 +324,7 @@ def add_additional_rule(entrance, rule):
def create_no_logic_connections(player, world, connections):
for entrance, parent_region, target_region, *rule_override in connections:
for entrance, parent_region, target_region, *_ in connections:
parent = world.get_region(parent_region, player)
target = world.get_region(target_region, player)
connection = Entrance(player, entrance, parent)
@@ -325,7 +334,7 @@ def create_no_logic_connections(player, world, connections):
def set_owg_rules(player, world, connections, default_rule):
for entrance, parent_region, target_region, *rule_override in connections:
for entrance, _, _, *rule_override in connections:
connection = world.get_entrance(entrance, player)
rule = rule_override[0] if len(rule_override) > 0 else default_rule
connection.access_rule = rule
@@ -463,7 +472,7 @@ boots_clips = [
(['C Whirlpool To Cliff Clip', 'Dark C Whirlpool To Cliff Clip'], ['C Whirlpool Area', 'Dark C Whirlpool Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['C Whirlpool Outer To Cliff Clip', 'Dark C Whirlpool Outer To Cliff Clip'], ['C Whirlpool Outer Area', 'Dark C Whirlpool Outer Area'], ['Central Cliffs', 'Dark Central Cliffs']),
(['South Teleporter Cliff Ledge Drop', 'Dark South Teleporter Cliff Ledge Drop'], ['C Whirlpool Area', 'Dark C Whirlpool Area'], ['Dark Central Cliffs', 'Central Cliffs']), # glove/pearl
(['C Whirlpool Portal Bomb Clip', 'Dark C Whirlpool Portal Bomb Clip'], ['C Whirlpool Portal Area', 'Dark C Whirlpool Portal Area'], ['Central Cliffs', 'Dark Central Cliffs']), # bomb TODO: bombbag not considered
(['Statues To Cliff Clip', 'Hype To Cliff Clip'], ['Statues Area', 'Hype Cave Area'], ['Central Cliffs', 'Dark Central Cliffs']),
@@ -495,6 +504,6 @@ mirror_clips = [
]
mirror_offsets = [
(['DM Offset Mirror', 'DDM Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Courtyard', 'Pyramid Area'], ['Pyramid Area', 'Hyrule Castle Courtyard']),
(['DM To HC Ledge Offset Mirror', 'DDM To HC Ledge Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', None], ['Pyramid Area', None])
(['DM Offset Mirror', 'DDM Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', 'Pyramid Crack'], ['Pyramid Area', 'Hyrule Castle Courtyard'])
#(['DM To HC Ledge Offset Mirror', 'DDM To HC Ledge Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', None], ['Pyramid Area', None])
]