diff --git a/BaseClasses.py b/BaseClasses.py index 2a6f5e88..2395d32e 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -765,7 +765,7 @@ class Location(object): self.item_rule = lambda item: True def can_fill(self, state, item, check_access=True): - return self.always_allow(item, self) or (self.parent_region.can_fill(item) and self.item_rule(item) and (not check_access or self.can_reach(state))) + return self.always_allow(state, item) or (self.parent_region.can_fill(item) and self.item_rule(item) and (not check_access or self.can_reach(state))) def can_reach(self, state): if self.access_rule(state) and state.can_reach(self.parent_region): diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 90504453..1afdf261 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -7,7 +7,12 @@ def link_entrances(world): connect_two_way(world, 'Links House', 'Links House Exit') # unshuffled. For now connect_exit(world, 'Chris Houlihan Room Exit', 'Links House') # should always match link's house, except for plandos - unbias_some_entrances() + Dungeon_Exits = Dungeon_Exits_Base.copy() + Cave_Exits = Cave_Exits_Base.copy() + Old_Man_House = Old_Man_House_Base.copy() + Cave_Three_Exits = Cave_Three_Exits_Base.copy() + + unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) # setup mandatory connections for exitname, regionname in mandatory_connections: @@ -1329,7 +1334,7 @@ def simple_shuffle_dungeons(world): connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Turtle Rock Ledge Exit (West)') connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Turtle Rock Ledge Exit (East)') -def unbias_some_entrances(): +def unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits): def shuffle_lists_in_list(ls): for i, item in enumerate(ls): if isinstance(item, list): @@ -1392,7 +1397,7 @@ DW_Dungeon_Entrances = ['Thieves Town', DW_Dungeon_Entrances_Must_Exit = ['Dark Death Mountain Ledge (East)', 'Turtle Rock Isolated Ledge Entrance'] -Dungeon_Exits = [['Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)'], +Dungeon_Exits_Base = [['Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)'], 'Desert Palace Exit (North)', 'Eastern Palace Exit', 'Tower of Hera Exit', @@ -1422,21 +1427,20 @@ Old_Man_Entrances = ['Old Man Cave (East)', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)'] -Old_Man_House = [['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)']] +Old_Man_House_Base = [['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)']] - -Cave_Exits = [['Elder House Exit (East)', 'Elder House Exit (West)'], +Cave_Exits_Base = [['Elder House Exit (East)', 'Elder House Exit (West)'], ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)'], ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)'], ['Fairy Ascension Cave Exit (Bottom)', 'Fairy Ascension Cave Exit (Top)'], ['Bumper Cave Exit (Top)', 'Bumper Cave Exit (Bottom)'], ['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']] -Cave_Exits += [('Superbunny Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)'), +Cave_Exits_Base += [('Superbunny Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)'), ('Spiral Cave Exit (Top)', 'Spiral Cave Exit')] - -Cave_Three_Exits = [('Spectacle Rock Cave Exit (Peak)', 'Spectacle Rock Cave Exit (Top)', + +Cave_Three_Exits_Base = [('Spectacle Rock Cave Exit (Peak)', 'Spectacle Rock Cave Exit (Top)', 'Spectacle Rock Cave Exit'), ['Paradox Cave Exit (Top)', 'Paradox Cave Exit (Middle)','Paradox Cave Exit (Bottom)']] diff --git a/ItemList.py b/ItemList.py index fb76afac..8c7f3d71 100644 --- a/ItemList.py +++ b/ItemList.py @@ -274,9 +274,6 @@ def generate_itempool(world): create_dynamic_shop_locations(world) - # distribute crystals - fill_prizes(world) - take_any_locations = [ 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Light World Bomb Hut', 'Fortune Teller (Light)', 'Lake Hylia Fortune Teller', 'Lumberjack House', 'Bonk Fairy (Light)', diff --git a/Main.py b/Main.py index 500e88bc..e7177011 100644 --- a/Main.py +++ b/Main.py @@ -13,7 +13,7 @@ from Rom import patch_rom, Sprite, LocalRom, JsonRom from Rules import set_rules from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive from Fill import distribute_items_cutoff, distribute_items_staleness, distribute_items_restrictive, flood_items -from ItemList import generate_itempool, difficulties +from ItemList import generate_itempool, difficulties, fill_prizes from Utils import output_path __version__ = '0.6.1' @@ -62,13 +62,17 @@ def main(args, seed=None): link_entrances(world) mark_light_world_regions(world) + logger.info('Generating Item Pool.') + + generate_itempool(world) + logger.info('Calculating Access Rules.') set_rules(world) - logger.info('Generating Item Pool.') + logger.info('Placing Dungeon Prizes.') - generate_itempool(world) + fill_prizes(world) logger.info('Placing Dungeon Items.') @@ -151,6 +155,9 @@ def copy_world(world): ret.dark_world_light_cone = world.dark_world_light_cone ret.seed = world.seed ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge + ret.can_access_trock_front = world.can_access_trock_front + ret.can_access_trock_big_chest = world.can_access_trock_big_chest + ret.can_access_trock_middle = world.can_access_trock_middle ret.can_take_damage = world.can_take_damage ret.difficulty_requirements = world.difficulty_requirements ret.fix_fake_world = world.fix_fake_world @@ -271,7 +278,8 @@ def create_playthrough(world): old_item = location.item location.item = None state.remove(old_item) - if world.can_beat_game(state_cache[num]): + ##if world.can_beat_game(state_cache[num]): + if world.can_beat_game(): to_delete.append(location) else: # still required, got to keep it around diff --git a/Rules.py b/Rules.py index 1f3fe0d7..8762945d 100644 --- a/Rules.py +++ b/Rules.py @@ -56,7 +56,6 @@ 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': @@ -572,7 +571,7 @@ def set_trock_key_rules(world): set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (North)'), lambda state: state.has_key('Small Key (Turtle Rock)', 2)) set_rule(world.get_entrance('Turtle Rock Pokey Room'), lambda state: state.has_key('Small Key (Turtle Rock)', 1)) set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has_key('Small Key (Turtle Rock)', tr_big_key_chest_keys_needed(state))) - set_always_allow(world.get_location('Turtle Rock - Big Key Chest'), lambda state, item: item.name == 'Small Key (Turtle Rock)') + set_always_allow(world.get_location('Turtle Rock - Big Key Chest'), lambda state, item: item.name == 'Small Key (Turtle Rock)' and state.has_key('Small Key (Turtle Rock)', 2)) non_big_key_locations += ['Turtle Rock - Crystaroller Room', 'Turtle Rock - Eye Bridge - Bottom Left', 'Turtle Rock - Eye Bridge - Bottom Right', 'Turtle Rock - Eye Bridge - Top Left', 'Turtle Rock - Eye Bridge - Top Right'] @@ -585,7 +584,6 @@ def set_trock_key_rules(world): 'Turtle Rock - Eye Bridge - Top Right'] if not world.keysanity: non_big_key_locations += ['Turtle Rock - Big Key Chest'] - else: set_rule(world.get_entrance('Turtle Rock (Chain Chomp Room) (South)'), lambda state: state.has_key('Small Key (Turtle Rock)', 2) if item_in_locations(state, 'Big Key (Turtle Rock)', ['Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right']) else state.has_key('Small Key (Turtle Rock)', 4)) set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: (state.has_key('Small Key (Turtle Rock)', 4) or item_name(state, 'Turtle Rock - Big Key Chest') == 'Small Key (Turtle Rock)'))