diff --git a/DoorShuffle.py b/DoorShuffle.py index a3e12987..33e42e63 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -8,10 +8,11 @@ from typing import DefaultDict, Dict, List from functools import reduce from BaseClasses import RegionType, Region, Door, DoorType, Direction, Sector, CrystalBarrier, DungeonInfo +from Doors import reset_portals from Dungeons import dungeon_regions, region_starts, standard_starts, split_region_starts from Dungeons import dungeon_bigs, dungeon_keys, dungeon_hints from Items import ItemFactory -from RoomData import DoorKind, PairedDoor +from RoomData import DoorKind, PairedDoor, reset_rooms from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances from DungeonGenerator import dungeon_portals, dungeon_drops, GenerationException @@ -32,12 +33,15 @@ def link_doors(world, player): for door in world.doors: if door.player == player: door.dest = None + door.entranceFlag = False ent = door.entrance if door.type != DoorType.Logical and ent.connected_region is not None: ent.connected_region.entrances = [x for x in ent.connected_region.entrances if x != ent] ent.connected_region = None for portal in world.dungeon_portals[player]: disconnect_portal(portal, world, player) + reset_portals(world, player) + reset_rooms(world, player) def link_doors_main(world, player): @@ -527,6 +531,7 @@ def disconnect_portal(portal, world, player): if edit_entrance in portal_entrance.parent_region.entrances: portal_entrance.parent_region.entrances.remove(edit_entrance) chosen_door.blocked = chosen_door.blocked_orig + chosen_door.entranceFlag = False def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False, bk_shuffle=False): @@ -734,7 +739,7 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_ if len(origin_list) <= 0 or not pre_validate(builder, origin_list, split_dungeon, world, player): if last_key == builder.name or loops > 1000: origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name if len(origin_list) > 0 else 'no origin' - raise Exception('Infinite loop detected for "%s" located at %s' % (builder.name, origin_name)) + raise GenerationException(f'Infinite loop detected for "{builder.name}" located at {origin_name}') sector_queue.append(builder) last_key = builder.name loops += 1 diff --git a/Doors.py b/Doors.py index 343dd6d1..9c40838f 100644 --- a/Doors.py +++ b/Doors.py @@ -1271,35 +1271,9 @@ def create_doors(world, player): assign_entrances(world, player) - dungeon_portals = [ - create_portal(player, 'Sanctuary', world.get_door('Sanctuary S', player), 0x02, 0x02), - create_portal(player, 'Hyrule Castle West', world.get_door('Hyrule Castle West Lobby S', player), 0x03, 0x04), - create_portal(player, 'Hyrule Castle South', world.get_door('Hyrule Castle Lobby S', player), 0x04, 0x06), - create_portal(player, 'Hyrule Castle East', world.get_door('Hyrule Castle East Lobby S', player), 0x05, 0x08), - create_portal(player, 'Eastern', world.get_door('Eastern Lobby S', player), 0x08, 0x12, 0), - create_portal(player, 'Desert South', world.get_door('Desert Main Lobby S', player), 0x09, 0x14), - create_portal(player, 'Desert East', world.get_door('Desert East Lobby S', player), 0x0a, 0x16), - create_portal(player, 'Desert West', world.get_door('Desert West S', player), 0x0b, 0x18), - create_portal(player, 'Desert Back', world.get_door('Desert Back Lobby S', player), 0x0c, 0x1a, 1), - create_portal(player, 'Turtle Rock Lazy Eyes', world.get_door('TR Lazy Eyes SE', player), 0x15, 0x2c), - create_portal(player, 'Turtle Rock Eye Bridge', world.get_door('TR Eye Bridge SW', player), 0x18, 0x32), - create_portal(player, 'Turtle Rock Chest', world.get_door('TR Big Chest Entrance SE', player), 0x19, 0x34), - create_portal(player, 'Agahnims Tower', world.get_door('Tower Lobby S', player), 0x24, 0x4a), - create_portal(player, 'Swamp', world.get_door('Swamp Lobby S', player), 0x25, 0x4c, 4), - create_portal(player, 'Palace of Darkness', world.get_door('PoD Lobby S', player), 0x26, 0x4e, 5), - create_portal(player, 'Mire', world.get_door('Mire Lobby S', player), 0x27, 0x50, 7), - create_portal(player, 'Skull 2 West', world.get_door('Skull 2 West Lobby S', player), 0x28, 0x52), - create_portal(player, 'Skull 2 East', world.get_door('Skull 2 East Lobby SW', player), 0x29, 0x54), - create_portal(player, 'Skull 1', world.get_door('Skull 1 Lobby S', player), 0x2a, 0x56), - create_portal(player, 'Skull 3', world.get_door('Skull 3 Lobby SW', player), 0x2b, 0x58, 6), - create_portal(player, 'Ice', world.get_door('Ice Lobby SE', player), 0x2d, 0x5c, 8), - create_portal(player, 'Hera', world.get_door('Hera Lobby S', player), 0x33, 0x5a, 2), - create_portal(player, 'Thieves Town', world.get_door('Thieves Lobby S', player), 0x34, 0x6a, 10), - create_portal(player, 'Turtle Rock Main', world.get_door('TR Main Lobby SE', player), 0x35, 0x68, 9), - create_portal(player, 'Ganons Tower', world.get_door('GT Lobby S', player), 0x37, 0x70), - ] - world.dungeon_portals[player] += dungeon_portals + create_portals(world, player) + # static portal flags world.get_door('Sanctuary S', player).dead_end(allowPassage=True) world.get_door('Eastern Hint Tile Blocked Path SE', player).passage = False world.get_door('TR Big Chest Entrance SE', player).passage = False @@ -1337,6 +1311,42 @@ def create_doors(world, player): world.get_door('Ice Conveyor SW', player).dungeonLink = 'linkIceFalls2' +def create_portals(world, player): + dungeon_portals = [ + create_portal(player, 'Sanctuary', world.get_door('Sanctuary S', player), 0x02, 0x02), + create_portal(player, 'Hyrule Castle West', world.get_door('Hyrule Castle West Lobby S', player), 0x03, 0x04), + create_portal(player, 'Hyrule Castle South', world.get_door('Hyrule Castle Lobby S', player), 0x04, 0x06), + create_portal(player, 'Hyrule Castle East', world.get_door('Hyrule Castle East Lobby S', player), 0x05, 0x08), + create_portal(player, 'Eastern', world.get_door('Eastern Lobby S', player), 0x08, 0x12, 0), + create_portal(player, 'Desert South', world.get_door('Desert Main Lobby S', player), 0x09, 0x14), + create_portal(player, 'Desert East', world.get_door('Desert East Lobby S', player), 0x0a, 0x16), + create_portal(player, 'Desert West', world.get_door('Desert West S', player), 0x0b, 0x18), + create_portal(player, 'Desert Back', world.get_door('Desert Back Lobby S', player), 0x0c, 0x1a, 1), + create_portal(player, 'Turtle Rock Lazy Eyes', world.get_door('TR Lazy Eyes SE', player), 0x15, 0x2c), + create_portal(player, 'Turtle Rock Eye Bridge', world.get_door('TR Eye Bridge SW', player), 0x18, 0x32), + create_portal(player, 'Turtle Rock Chest', world.get_door('TR Big Chest Entrance SE', player), 0x19, 0x34), + create_portal(player, 'Agahnims Tower', world.get_door('Tower Lobby S', player), 0x24, 0x4a), + create_portal(player, 'Swamp', world.get_door('Swamp Lobby S', player), 0x25, 0x4c, 4), + create_portal(player, 'Palace of Darkness', world.get_door('PoD Lobby S', player), 0x26, 0x4e, 5), + create_portal(player, 'Mire', world.get_door('Mire Lobby S', player), 0x27, 0x50, 7), + create_portal(player, 'Skull 2 West', world.get_door('Skull 2 West Lobby S', player), 0x28, 0x52), + create_portal(player, 'Skull 2 East', world.get_door('Skull 2 East Lobby SW', player), 0x29, 0x54), + create_portal(player, 'Skull 1', world.get_door('Skull 1 Lobby S', player), 0x2a, 0x56), + create_portal(player, 'Skull 3', world.get_door('Skull 3 Lobby SW', player), 0x2b, 0x58, 6), + create_portal(player, 'Ice', world.get_door('Ice Lobby SE', player), 0x2d, 0x5c, 8), + create_portal(player, 'Hera', world.get_door('Hera Lobby S', player), 0x33, 0x5a, 2), + create_portal(player, 'Thieves Town', world.get_door('Thieves Lobby S', player), 0x34, 0x6a, 10), + create_portal(player, 'Turtle Rock Main', world.get_door('TR Main Lobby SE', player), 0x35, 0x68, 9), + create_portal(player, 'Ganons Tower', world.get_door('GT Lobby S', player), 0x37, 0x70), + ] + world.dungeon_portals[player] += dungeon_portals + + +def reset_portals(world, player): + world.dungeon_portals[player].clear() + world._portal_cache.clear() + create_portals(world, player) + def create_paired_doors(world, player): world.paired_doors[player] = [ PairedDoor('Sewers Secret Room Key Door S', 'Sewers Key Rat Key Door N', True), diff --git a/Main.py b/Main.py index e675156c..69351f7a 100644 --- a/Main.py +++ b/Main.py @@ -433,7 +433,7 @@ def copy_world(world): copied_region.is_light_world = region.is_light_world copied_region.is_dark_world = region.is_dark_world copied_region.dungeon = region.dungeon - copied_region.locations = [Location(location.player, location.name, parent=copied_region) for location in region.locations] + copied_region.locations = [ret.get_location(location.name, location.player) for location in region.locations] for entrance in region.entrances: ret.get_entrance(entrance.name, entrance.player).connect(copied_region) diff --git a/RoomData.py b/RoomData.py index ac740c90..3fe8d594 100644 --- a/RoomData.py +++ b/RoomData.py @@ -254,6 +254,12 @@ def create_rooms(world, player): world.get_room(0xc0, player).change(0, DoorKind.Normal) # fix this kill room if enemizer is on +def reset_rooms(world, player): + world.rooms = [x for x in world.rooms if x.player != player] + world._room_cache.clear() + create_rooms(world, player) + + class Room(object): def __init__(self, player, index, address): self.player = player