diff --git a/Main.py b/Main.py index 4e7e5c01..18426f02 100644 --- a/Main.py +++ b/Main.py @@ -267,10 +267,84 @@ def main(args, seed=None): return world +def copy_world(world): + # ToDo: Not good yet + ret = World(world.players, world.shuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints) + ret.teams = world.teams + ret.player_names = copy.deepcopy(world.player_names) + ret.remote_items = world.remote_items.copy() + ret.required_medallions = world.required_medallions.copy() + ret.swamp_patch_required = world.swamp_patch_required.copy() + ret.ganon_at_pyramid = world.ganon_at_pyramid.copy() + ret.powder_patch_required = world.powder_patch_required.copy() + ret.ganonstower_vanilla = world.ganonstower_vanilla.copy() + ret.treasure_hunt_count = world.treasure_hunt_count.copy() + ret.treasure_hunt_icon = world.treasure_hunt_icon.copy() + ret.sewer_light_cone = world.sewer_light_cone.copy() + ret.light_world_light_cone = world.light_world_light_cone + ret.dark_world_light_cone = world.dark_world_light_cone + ret.seed = world.seed + ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge.copy() + ret.can_access_trock_front = world.can_access_trock_front.copy() + ret.can_access_trock_big_chest = world.can_access_trock_big_chest.copy() + ret.can_access_trock_middle = world.can_access_trock_middle.copy() + ret.can_take_damage = world.can_take_damage + ret.difficulty_requirements = world.difficulty_requirements.copy() + ret.fix_fake_world = world.fix_fake_world.copy() + ret.lamps_needed_for_dark_rooms = world.lamps_needed_for_dark_rooms + ret.mapshuffle = world.mapshuffle.copy() + ret.compassshuffle = world.compassshuffle.copy() + ret.keyshuffle = world.keyshuffle.copy() + ret.bigkeyshuffle = world.bigkeyshuffle.copy() + ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy() + ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy() + ret.open_pyramid = world.open_pyramid.copy() + ret.boss_shuffle = world.boss_shuffle.copy() + ret.enemy_shuffle = world.enemy_shuffle.copy() + ret.enemy_health = world.enemy_health.copy() + ret.enemy_damage = world.enemy_damage.copy() + ret.beemizer = world.beemizer.copy() + ret.timer = world.timer.copy() + ret.shufflepots = world.shufflepots.copy() + ret.extendedmsu = world.extendedmsu.copy() + ret.regions = [copy.copy(region) for region in world.regions] + ret.shops = [copy.copy(shop) for shop in world.shops] + ret.dungeons = [copy.copy(dungeon) for dungeon in world.dungeons] + ret.itempool = world.itempool + ret.precollected_items = world.precollected_items.copy() + + for shop in ret.shops: + shop.inventory = shop.inventory.copy() + + ret.initialize_regions() + + # Copy locations + for region in ret.regions: + region.locations = [copy.copy(location) for location in region.locations] + for location in region.locations: + location.parent_region = region + region.entrances = [copy.copy(entrance) for entrance in region.entrances] + for entrance in region.entrances: + entrance.connected_region = region + entrance.parent_region = ret.get_region(entrance.parent_region.name, entrance.parent_region.player) + region.exits = [copy.copy(exit) for exit in region.exits] + for exit in region.exits: + exit.parent_region = region + exit.connected_region = ret.get_region(entrance.connected_region.name, entrance.connected_region.player) + + # copy state + ret.state = ret.state.copy() + ret.state.world = ret + ret.state.prog_items = world.state.prog_items.copy() + ret.state.stale = {player: True for player in range(1, world.players + 1)} + + return ret + + def create_playthrough(world): # create a copy as we will modify it old_world = world - world = copy.deepcopy(world) + world = copy_world(world) # if we only check for beatable, we can do this sanity check first before writing down spheres if not world.can_beat_game(): diff --git a/Rules.py b/Rules.py index da76a4b5..eb5869d7 100644 --- a/Rules.py +++ b/Rules.py @@ -188,16 +188,16 @@ def global_rules(world, player): set_rule(world.get_location('Castle Tower - Dark Maze', player), lambda state: state.can_kill_most_things(player, 8) and state.has_key('Small Key (Agahnims Tower)', player)) set_rule(world.get_location('Eastern Palace - Big Chest', player), lambda state: state.has('Big Key (Eastern Palace)', player)) - set_rule(world.get_location('Eastern Palace - Boss', player), lambda state: state.can_shoot_arrows(player) and state.has('Big Key (Eastern Palace)', player) and world.get_location('Eastern Palace - Boss', player).parent_region.dungeon.boss.can_defeat(state)) - set_rule(world.get_location('Eastern Palace - Prize', player), lambda state: state.can_shoot_arrows(player) and state.has('Big Key (Eastern Palace)', player) and world.get_location('Eastern Palace - Prize', player).parent_region.dungeon.boss.can_defeat(state)) + set_rule(world.get_location('Eastern Palace - Boss', player), lambda state: state.can_shoot_arrows(player) and state.has('Big Key (Eastern Palace)', player) and state.world.get_location('Eastern Palace - Boss', player).parent_region.dungeon.boss.can_defeat(state)) + set_rule(world.get_location('Eastern Palace - Prize', player), lambda state: state.can_shoot_arrows(player) and state.has('Big Key (Eastern Palace)', player) and state.world.get_location('Eastern Palace - Prize', player).parent_region.dungeon.boss.can_defeat(state)) for location in ['Eastern Palace - Boss', 'Eastern Palace - Big Chest']: forbid_item(world.get_location(location, player), 'Big Key (Eastern Palace)', player) set_rule(world.get_location('Desert Palace - Big Chest', player), lambda state: state.has('Big Key (Desert Palace)', player)) set_rule(world.get_location('Desert Palace - Torch', player), lambda state: state.has_Boots(player)) set_rule(world.get_entrance('Desert Palace East Wing', player), lambda state: state.has_key('Small Key (Desert Palace)', player)) - set_rule(world.get_location('Desert Palace - Prize', player), lambda state: state.has_key('Small Key (Desert Palace)', player) and state.has('Big Key (Desert Palace)', player) and state.has_fire_source(player) and world.get_location('Desert Palace - Prize', player).parent_region.dungeon.boss.can_defeat(state)) - set_rule(world.get_location('Desert Palace - Boss', player), lambda state: state.has_key('Small Key (Desert Palace)', player) and state.has('Big Key (Desert Palace)', player) and state.has_fire_source(player) and world.get_location('Desert Palace - Boss', player).parent_region.dungeon.boss.can_defeat(state)) + set_rule(world.get_location('Desert Palace - Prize', player), lambda state: state.has_key('Small Key (Desert Palace)', player) and state.has('Big Key (Desert Palace)', player) and state.has_fire_source(player) and state.world.get_location('Desert Palace - Prize', player).parent_region.dungeon.boss.can_defeat(state)) + set_rule(world.get_location('Desert Palace - Boss', player), lambda state: state.has_key('Small Key (Desert Palace)', player) and state.has('Big Key (Desert Palace)', player) and state.has_fire_source(player) and state.world.get_location('Desert Palace - Boss', player).parent_region.dungeon.boss.can_defeat(state)) for location in ['Desert Palace - Boss', 'Desert Palace - Big Chest']: forbid_item(world.get_location(location, player), 'Big Key (Desert Palace)', player) @@ -362,15 +362,15 @@ def global_rules(world, player): set_rule(world.get_location('Ganons Tower - Big Chest', player), lambda state: state.has('Big Key (Ganons Tower)', player)) - set_rule(world.get_location('Ganons Tower - Big Key Room - Left', player), lambda state: world.get_location('Ganons Tower - Big Key Room - Left', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) - set_rule(world.get_location('Ganons Tower - Big Key Chest', player), lambda state: world.get_location('Ganons Tower - Big Key Chest', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) - set_rule(world.get_location('Ganons Tower - Big Key Room - Right', player), lambda state: world.get_location('Ganons Tower - Big Key Room - Right', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) + set_rule(world.get_location('Ganons Tower - Big Key Room - Left', player), lambda state: state.world.get_location('Ganons Tower - Big Key Room - Left', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) + set_rule(world.get_location('Ganons Tower - Big Key Chest', player), lambda state: state.world.get_location('Ganons Tower - Big Key Chest', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) + set_rule(world.get_location('Ganons Tower - Big Key Room - Right', player), lambda state: state.world.get_location('Ganons Tower - Big Key Room - Right', player).parent_region.dungeon.bosses['bottom'].can_defeat(state)) set_rule(world.get_entrance('Ganons Tower Big Key Door', player), lambda state: state.has('Big Key (Ganons Tower)', player) and state.can_shoot_arrows(player)) - set_rule(world.get_entrance('Ganons Tower Torch Rooms', player), lambda state: state.has_fire_source(player) and world.get_entrance('Ganons Tower Torch Rooms', player).parent_region.dungeon.bosses['middle'].can_defeat(state)) + set_rule(world.get_entrance('Ganons Tower Torch Rooms', player), lambda state: state.has_fire_source(player) and state.world.get_entrance('Ganons Tower Torch Rooms', player).parent_region.dungeon.bosses['middle'].can_defeat(state)) set_rule(world.get_location('Ganons Tower - Pre-Moldorm Chest', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 3)) set_rule(world.get_entrance('Ganons Tower Moldorm Door', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 4)) - set_rule(world.get_entrance('Ganons Tower Moldorm Gap', player), lambda state: state.has('Hookshot', player) and world.get_entrance('Ganons Tower Moldorm Gap', player).parent_region.dungeon.bosses['top'].can_defeat(state)) + set_rule(world.get_entrance('Ganons Tower Moldorm Gap', player), lambda state: state.has('Hookshot', player) and state.world.get_entrance('Ganons Tower Moldorm Gap', player).parent_region.dungeon.bosses['top'].can_defeat(state)) set_defeat_dungeon_boss_rule(world.get_location('Agahnim 2', player)) for location in ['Ganons Tower - Big Chest', 'Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right', 'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Validation Chest']: @@ -889,7 +889,7 @@ def set_trock_key_rules(world, player): if world.accessibility[player] != 'locations': set_always_allow(world.get_location('Turtle Rock - Big Key Chest', player), lambda state, item: item.name == 'Small Key (Turtle Rock)' and item.player == player - and state.can_reach(world.get_region('Turtle Rock (Second Section)', player))) + and state.can_reach(state.world.get_region('Turtle Rock (Second Section)', player))) else: forbid_item(world.get_location('Turtle Rock - Big Key Chest', player), 'Small Key (Turtle Rock)', player)