diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 170233ce..948115f3 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -3320,6 +3320,7 @@ def check_for_valid_layout(builder, sector_list, builder_info): possible_regions.add(portal.door.entrance.parent_region.name) if builder.name in dungeon_drops.keys(): possible_regions.update(dungeon_drops[builder.name]) + independents = find_independent_entrances(possible_regions, world, player) for name, split_build in builder.split_dungeon_map.items(): name_bits = name.split(" ") orig_name = " ".join(name_bits[:-1]) @@ -3332,7 +3333,8 @@ def check_for_valid_layout(builder, sector_list, builder_info): if r_name not in entrance_regions: entrance_regions.append(r_name) # entrance_regions = [x for x in entrance_regions if x not in split_check_entrance_invalid] - proposal = generate_dungeon_find_proposal(split_build, entrance_regions, True, world, player) + split = any(x for x in independents if x not in entrance_regions) + proposal = generate_dungeon_find_proposal(split_build, entrance_regions, split, world, player) # record split proposals builder.valid_proposal[name] = proposal builder.exception_list = list(sector_list) @@ -3347,6 +3349,32 @@ def check_for_valid_layout(builder, sector_list, builder_info): return len(unreached_doors) == 0, unreached_doors +def find_independent_entrances(entrance_regions, world, player): + independents = set() + for region in entrance_regions: + portal = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region.name == region), None) + if portal: + if portal.destination: + continue + elif len(entrance_regions) > 1: + p_region = portal.door.entrance.connected_region + access_region = next(x.parent_region for x in p_region.entrances + if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld]) + if access_region.name in world.inaccessible_regions[player]: + continue + else: + r = world.get_region(region, player) + access_region = next(x.parent_region for x in r.entrances + if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] + or x.parent_region.name == 'Sewer Drop') + if access_region.name == 'Sewer Drop': + access_region = next(x.parent_region for x in access_region.entrances) + if access_region.name in world.inaccessible_regions[player]: + continue + independents.add(region) + return independents + + def resolve_equations(builder, sector_list): unreached_doors = defaultdict(list) equations = {x: y for x, y in copy_door_equations(builder, sector_list).items() if len(y) > 0} diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index 5cf88dc0..cf18f4f4 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -1385,10 +1385,12 @@ def validate_key_layout(key_layout, world, player): state.big_key_special = check_bk_special(key_layout.sector.regions, world, player) for region in key_layout.start_regions: dungeon_entrance, portal_door = find_outside_connection(region) - if (key_layout.prize_relevant and dungeon_entrance and - dungeon_entrance.name in ['Ganons Tower', 'Inverted Ganons Tower', 'Pyramid Fairy']): + if (len(key_layout.start_regions) > 1 and dungeon_entrance and + dungeon_entrance.name in ['Ganons Tower', 'Inverted Ganons Tower', 'Pyramid Fairy'] + and key_layout.key_logic.dungeon in dungeon_prize): state.append_door_to_list(portal_door, state.prize_doors) state.prize_door_set[portal_door] = dungeon_entrance + key_layout.prize_relevant = True else: state.visit_region(region, key_checks=True) state.add_all_doors_check_keys(region, flat_proposal, world, player) @@ -1419,6 +1421,8 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa if smalls_done and bk_done: return False else: + # todo: pretty sure you should OR these paths together, maybe when there's one location and it can + # either be small or big key if smalls_avail and available_small_locations > 0: for exp_door in state.small_doors: state_copy = state.copy() @@ -1449,6 +1453,7 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa valid = checked_states[code] if not valid: return False + # todo: feel like you only open these if the boss is available??? if not state.prize_doors_opened and key_layout.prize_relevant: state_copy = state.copy() open_a_door(next(iter(state_copy.prize_door_set)), state_copy, flat_proposal, world, player)