Partial vt28 logic update
This commit is contained in:
		
							parent
							
								
									1c587f9ce1
								
							
						
					
					
						commit
						3adf4fadd1
					
				| 
						 | 
					@ -52,6 +52,7 @@ class World(object):
 | 
				
			||||||
        self.fastmenu = fastmenu
 | 
					        self.fastmenu = fastmenu
 | 
				
			||||||
        self.disable_music = disable_music
 | 
					        self.disable_music = disable_music
 | 
				
			||||||
        self.keysanity = keysanity
 | 
					        self.keysanity = keysanity
 | 
				
			||||||
 | 
					        self.can_take_damage = True
 | 
				
			||||||
        self.spoiler = Spoiler(self)
 | 
					        self.spoiler = Spoiler(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def intialize_regions(self):
 | 
					    def intialize_regions(self):
 | 
				
			||||||
| 
						 | 
					@ -151,7 +152,7 @@ class World(object):
 | 
				
			||||||
        if not isinstance(location, Location):
 | 
					        if not isinstance(location, Location):
 | 
				
			||||||
            location = self.get_location(location)
 | 
					            location = self.get_location(location)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if location.can_fill(item):
 | 
					        if location.can_fill(self.state, item, False):
 | 
				
			||||||
            location.item = item
 | 
					            location.item = item
 | 
				
			||||||
            item.location = location
 | 
					            item.location = location
 | 
				
			||||||
            if collect:
 | 
					            if collect:
 | 
				
			||||||
| 
						 | 
					@ -351,6 +352,17 @@ class CollectionState(object):
 | 
				
			||||||
    def can_lift_heavy_rocks(self):
 | 
					    def can_lift_heavy_rocks(self):
 | 
				
			||||||
        return self.has('Titans Mitts')
 | 
					        return self.has('Titans Mitts')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def can_extend_magic(self):
 | 
				
			||||||
 | 
					        return self.has('Half Magic') or self.has('Quarter Magic') or self.has_bottle() # FIXME bottle should really also have a requirement that we can reach some shop that sells green or blue potions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def can_kill_most_things(self, enemies=5):
 | 
				
			||||||
 | 
					        return (self.has_blunt_weapon()
 | 
				
			||||||
 | 
					                or self.has('Cane of Somaria')
 | 
				
			||||||
 | 
					                or (self.has('Cane of Byrna') and (enemies < 6 or self.can_extend_Magic()))
 | 
				
			||||||
 | 
					                or self.has('Bow')
 | 
				
			||||||
 | 
					                or self.has('Fire Rod')
 | 
				
			||||||
 | 
					               )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def has_sword(self):
 | 
					    def has_sword(self):
 | 
				
			||||||
        return self.has('Fighter Sword') or self.has('Master Sword') or self.has('Tempered Sword') or self.has('Golden Sword')
 | 
					        return self.has('Fighter Sword') or self.has('Master Sword') or self.has('Tempered Sword') or self.has('Golden Sword')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -580,11 +592,12 @@ class Location(object):
 | 
				
			||||||
        self.recursion_count = 0
 | 
					        self.recursion_count = 0
 | 
				
			||||||
        self.staleness_count = 0
 | 
					        self.staleness_count = 0
 | 
				
			||||||
        self.event = False
 | 
					        self.event = False
 | 
				
			||||||
 | 
					        self.always_allow = lambda item, state: False
 | 
				
			||||||
        self.access_rule = lambda state: True
 | 
					        self.access_rule = lambda state: True
 | 
				
			||||||
        self.item_rule = lambda state: True
 | 
					        self.item_rule = lambda item: True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def can_fill(self, item):
 | 
					    def can_fill(self, state, item, check_access=True):
 | 
				
			||||||
        return self.parent_region.can_fill(item) and self.item_rule(item)
 | 
					        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)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def can_reach(self, state):
 | 
					    def can_reach(self, state):
 | 
				
			||||||
        if self.access_rule(state) and state.can_reach(self.parent_region):
 | 
					        if self.access_rule(state) and state.can_reach(self.parent_region):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								Fill.py
								
								
								
								
							
							
						
						
									
										19
									
								
								Fill.py
								
								
								
								
							| 
						 | 
					@ -57,7 +57,7 @@ def distribute_items_cutoff(world, cutoffrate=0.33):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        spot_to_fill = None
 | 
					        spot_to_fill = None
 | 
				
			||||||
        for location in fill_locations if placed_advancement_items / total_advancement_items < cutoffrate else reversed(fill_locations):
 | 
					        for location in fill_locations if placed_advancement_items / total_advancement_items < cutoffrate else reversed(fill_locations):
 | 
				
			||||||
            if world.state.can_reach(location) and location.can_fill(item_to_place):
 | 
					            if location.can_fill(world.state, item_to_place):
 | 
				
			||||||
                spot_to_fill = location
 | 
					                spot_to_fill = location
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,7 +129,7 @@ def distribute_items_staleness(world):
 | 
				
			||||||
            if not progress_done and random.randint(0, location.staleness_count) > 2:
 | 
					            if not progress_done and random.randint(0, location.staleness_count) > 2:
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if world.state.can_reach(location) and location.can_fill(item_to_place):
 | 
					            if location.can_fill(world.state, item_to_place):
 | 
				
			||||||
                spot_to_fill = location
 | 
					                spot_to_fill = location
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
| 
						 | 
					@ -138,7 +138,7 @@ def distribute_items_staleness(world):
 | 
				
			||||||
        # might have skipped too many locations due to potential staleness. Do not check for staleness now to find a candidate
 | 
					        # might have skipped too many locations due to potential staleness. Do not check for staleness now to find a candidate
 | 
				
			||||||
        if spot_to_fill is None:
 | 
					        if spot_to_fill is None:
 | 
				
			||||||
            for location in fill_locations:
 | 
					            for location in fill_locations:
 | 
				
			||||||
                if world.state.can_reach(location) and location.can_fill(item_to_place):
 | 
					                if location.can_fill(world.state, item_to_place):
 | 
				
			||||||
                    spot_to_fill = location
 | 
					                    spot_to_fill = location
 | 
				
			||||||
                    break
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,15 +168,16 @@ def fill_restrictive(world, base_state, locations, itempool):
 | 
				
			||||||
        item_to_place = itempool.pop()
 | 
					        item_to_place = itempool.pop()
 | 
				
			||||||
        maximum_exploration_state = sweep_from_pool()
 | 
					        maximum_exploration_state = sweep_from_pool()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        perform_access_check = True
 | 
				
			||||||
        if world.check_beatable_only:
 | 
					        if world.check_beatable_only:
 | 
				
			||||||
            can_beat_without = world.has_beaten_game(maximum_exploration_state)
 | 
					            perform_access_check = not world.has_beaten_game(maximum_exploration_state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        spot_to_fill = None
 | 
					        spot_to_fill = None
 | 
				
			||||||
        for location in locations:
 | 
					        for location in locations:
 | 
				
			||||||
            if location.can_fill(item_to_place):
 | 
					            if location.can_fill(maximum_exploration_state, item_to_place, perform_access_check):
 | 
				
			||||||
                if (world.check_beatable_only and can_beat_without) or maximum_exploration_state.can_reach(location):
 | 
					                spot_to_fill = location
 | 
				
			||||||
                    spot_to_fill = location
 | 
					                break
 | 
				
			||||||
                    break
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if spot_to_fill is None:
 | 
					        if spot_to_fill is None:
 | 
				
			||||||
            # we filled all reachable spots. Maybe the game can be beaten anyway?
 | 
					            # we filled all reachable spots. Maybe the game can be beaten anyway?
 | 
				
			||||||
| 
						 | 
					@ -251,7 +252,7 @@ def flood_items(world):
 | 
				
			||||||
        random.shuffle(location_list)
 | 
					        random.shuffle(location_list)
 | 
				
			||||||
        spot_to_fill = None
 | 
					        spot_to_fill = None
 | 
				
			||||||
        for location in location_list:
 | 
					        for location in location_list:
 | 
				
			||||||
            if world.state.can_reach(location) and location.can_fill(itempool[0]):
 | 
					            if location.can_fill(world.state, itempool[0]):
 | 
				
			||||||
                spot_to_fill = location
 | 
					                spot_to_fill = location
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,6 +180,9 @@ def generate_itempool(world):
 | 
				
			||||||
            or world.mode not in ['open', 'standard', 'swordless'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
 | 
					            or world.mode not in ['open', 'standard', 'swordless'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
 | 
				
			||||||
        raise NotImplementedError('Not supported yet')
 | 
					        raise NotImplementedError('Not supported yet')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if world.timer in ['ohko', 'timed-ohko']:
 | 
				
			||||||
 | 
					        world.can_take_damage = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    world.push_item('Ganon', ItemFactory('Triforce'), False)
 | 
					    world.push_item('Ganon', ItemFactory('Triforce'), False)
 | 
				
			||||||
    world.get_location('Ganon').event = True
 | 
					    world.get_location('Ganon').event = True
 | 
				
			||||||
    world.push_item('Agahnim 1', ItemFactory('Beat Agahnim 1'), False)
 | 
					    world.push_item('Agahnim 1', ItemFactory('Beat Agahnim 1'), False)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								Main.py
								
								
								
								
							
							
						
						
									
										1
									
								
								Main.py
								
								
								
								
							| 
						 | 
					@ -133,6 +133,7 @@ def copy_world(world):
 | 
				
			||||||
    ret.dark_world_light_cone = world.dark_world_light_cone
 | 
					    ret.dark_world_light_cone = world.dark_world_light_cone
 | 
				
			||||||
    ret.seed = world.seed
 | 
					    ret.seed = world.seed
 | 
				
			||||||
    ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge
 | 
					    ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge
 | 
				
			||||||
 | 
					    ret.can_take_damage = world.can_take_damage
 | 
				
			||||||
    create_regions(ret)
 | 
					    create_regions(ret)
 | 
				
			||||||
    create_dungeons(ret)
 | 
					    create_dungeons(ret)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								Rules.py
								
								
								
								
							
							
						
						
									
										76
									
								
								Rules.py
								
								
								
								
							| 
						 | 
					@ -39,6 +39,9 @@ def set_rules(world):
 | 
				
			||||||
def set_rule(spot, rule):
 | 
					def set_rule(spot, rule):
 | 
				
			||||||
    spot.access_rule = rule
 | 
					    spot.access_rule = rule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def set_always_allow(spot, rule):
 | 
				
			||||||
 | 
					    spot.always_allow = rule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def add_rule(spot, rule, combine='and'):
 | 
					def add_rule(spot, rule, combine='and'):
 | 
				
			||||||
    old_rule = spot.access_rule
 | 
					    old_rule = spot.access_rule
 | 
				
			||||||
| 
						 | 
					@ -60,10 +63,15 @@ def forbid_item(location, item):
 | 
				
			||||||
def item_in_locations(state, item, locations):
 | 
					def item_in_locations(state, item, locations):
 | 
				
			||||||
    for location in locations:
 | 
					    for location in locations:
 | 
				
			||||||
        loc = state.world.get_location(location)
 | 
					        loc = state.world.get_location(location)
 | 
				
			||||||
        if loc.item is not None and loc.item.name == item:
 | 
					        if item_name(loc) == item:
 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
    return False
 | 
					    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def item_name(location):
 | 
				
			||||||
 | 
					    if location.item is None:
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					    return location.item.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def global_rules(world):
 | 
					def global_rules(world):
 | 
				
			||||||
    # ganon can only carry triforce
 | 
					    # ganon can only carry triforce
 | 
				
			||||||
| 
						 | 
					@ -111,6 +119,7 @@ def global_rules(world):
 | 
				
			||||||
    set_rule(world.get_location('Master Sword Pedestal'), lambda state: state.has('Red Pendant') and state.has('Blue Pendant') and state.has('Green Pendant'))
 | 
					    set_rule(world.get_location('Master Sword Pedestal'), lambda state: state.has('Red Pendant') and state.has('Blue Pendant') and state.has('Green Pendant'))
 | 
				
			||||||
    set_rule(world.get_location('Sahasrahla'), lambda state: state.has('Green Pendant'))
 | 
					    set_rule(world.get_location('Sahasrahla'), lambda state: state.has('Green Pendant'))
 | 
				
			||||||
    set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has_beam_sword() or state.has('Beat Agahnim 1'))  # barrier gets removed after killing agahnim, relevant for entrance shuffle
 | 
					    set_rule(world.get_entrance('Agahnims Tower'), lambda state: state.has('Cape') or state.has_beam_sword() or state.has('Beat Agahnim 1'))  # barrier gets removed after killing agahnim, relevant for entrance shuffle
 | 
				
			||||||
 | 
					    # FIXME: VT has a can_kill_most_things(8) call on Aga Tower's entrance. I suspect this needs to be added to first two chests inside the tower instead?
 | 
				
			||||||
    set_rule(world.get_entrance('Agahnim 1'), lambda state: state.has_sword() and state.has('Small Key (Agahnims Tower)', 2))
 | 
					    set_rule(world.get_entrance('Agahnim 1'), lambda state: state.has_sword() and state.has('Small Key (Agahnims Tower)', 2))
 | 
				
			||||||
    set_rule(world.get_location('Castle Tower - Dark Maze'), lambda state: state.has('Small Key (Agahnims Tower)'))
 | 
					    set_rule(world.get_location('Castle Tower - Dark Maze'), lambda state: state.has('Small Key (Agahnims Tower)'))
 | 
				
			||||||
    set_rule(world.get_entrance('Top of Pyramid'), lambda state: state.has('Beat Agahnim 1'))
 | 
					    set_rule(world.get_entrance('Top of Pyramid'), lambda state: state.has('Beat Agahnim 1'))
 | 
				
			||||||
| 
						 | 
					@ -175,7 +184,9 @@ def global_rules(world):
 | 
				
			||||||
    set_rule(world.get_entrance('Fairy Ascension Mirror Spot'), lambda state: state.has_Mirror() and state.has_Pearl())  # need to lift flowers
 | 
					    set_rule(world.get_entrance('Fairy Ascension Mirror Spot'), lambda state: state.has_Mirror() and state.has_Pearl())  # need to lift flowers
 | 
				
			||||||
    set_rule(world.get_entrance('Isolated Ledge Mirror Spot'), lambda state: state.has_Mirror())
 | 
					    set_rule(world.get_entrance('Isolated Ledge Mirror Spot'), lambda state: state.has_Mirror())
 | 
				
			||||||
    set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)'), lambda state: False)  # Cannot get to bottom exit from top. Just exists for shuffling
 | 
					    set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)'), lambda state: False)  # Cannot get to bottom exit from top. Just exists for shuffling
 | 
				
			||||||
    set_rule(world.get_location('Spike Cave'), lambda state: state.has('Hammer') and state.can_lift_rocks() and (state.has('Cane of Byrna') or state.has('Cape')) and (state.has_bottle() or state.has('Half Magic') or state.has('Quarter Magic')))
 | 
					    set_rule(world.get_location('Spike Cave'), lambda state: state.has('Hammer') and state.can_lift_rocks() and (state.has('Cane of Byrna') or state.has('Cape')) and state.can_extend_magic())
 | 
				
			||||||
 | 
					    # TODO: Current-VT logic is: hammer and lift_rocks and ((cape and extend) or (byrna and (can-take-damage OR canextend)))
 | 
				
			||||||
 | 
					    # Is that really good enough? Can you really get through with byrna, single magic w/o refills and only 3 hearts?
 | 
				
			||||||
    set_rule(world.get_location('Hookshot Cave - Top Right'), lambda state: state.has('Hookshot'))
 | 
					    set_rule(world.get_location('Hookshot Cave - Top Right'), lambda state: state.has('Hookshot'))
 | 
				
			||||||
    set_rule(world.get_location('Hookshot Cave - Top Left'), lambda state: state.has('Hookshot'))
 | 
					    set_rule(world.get_location('Hookshot Cave - Top Left'), lambda state: state.has('Hookshot'))
 | 
				
			||||||
    set_rule(world.get_location('Hookshot Cave - Bottom Right'), lambda state: state.has('Hookshot') or state.has('Pegasus Boots'))
 | 
					    set_rule(world.get_location('Hookshot Cave - Bottom Right'), lambda state: state.has('Hookshot') or state.has('Pegasus Boots'))
 | 
				
			||||||
| 
						 | 
					@ -230,6 +241,7 @@ def global_rules(world):
 | 
				
			||||||
    set_rule(world.get_entrance('Thieves Town Big Key Door'), lambda state: state.has('Big Key (Thieves Town)'))
 | 
					    set_rule(world.get_entrance('Thieves Town Big Key Door'), lambda state: state.has('Big Key (Thieves Town)'))
 | 
				
			||||||
    set_rule(world.get_entrance('Blind Fight'), lambda state: state.has('Small Key (Thieves Town)') and (state.has_blunt_weapon() or state.has('Cane of Somaria') or state.has('Cane of Byrna')))
 | 
					    set_rule(world.get_entrance('Blind Fight'), lambda state: state.has('Small Key (Thieves Town)') and (state.has_blunt_weapon() or state.has('Cane of Somaria') or state.has('Cane of Byrna')))
 | 
				
			||||||
    set_rule(world.get_location('Thieves\' Town - Big Chest'), lambda state: state.has('Small Key (Thieves Town)') and state.has('Hammer'))
 | 
					    set_rule(world.get_location('Thieves\' Town - Big Chest'), lambda state: state.has('Small Key (Thieves Town)') and state.has('Hammer'))
 | 
				
			||||||
 | 
					    # TODO: add key-for-key logic to above w always_allow, etc.
 | 
				
			||||||
    set_rule(world.get_location('Thieves\' Town - Attic'), lambda state: state.has('Small Key (Thieves Town)'))
 | 
					    set_rule(world.get_location('Thieves\' Town - Attic'), lambda state: state.has('Small Key (Thieves Town)'))
 | 
				
			||||||
    for location in ['Thieves\' Town - Attic', 'Thieves\' Town - Big Chest', 'Thieves\' Town - Blind\'s Cell', 'Thieves Town - Blind']:
 | 
					    for location in ['Thieves\' Town - Attic', 'Thieves\' Town - Big Chest', 'Thieves\' Town - Blind\'s Cell', 'Thieves Town - Blind']:
 | 
				
			||||||
        forbid_item(world.get_location(location), 'Big Key (Thieves Town)')
 | 
					        forbid_item(world.get_location(location), 'Big Key (Thieves Town)')
 | 
				
			||||||
| 
						 | 
					@ -250,14 +262,14 @@ def global_rules(world):
 | 
				
			||||||
    set_rule(world.get_entrance('Ice Palace Entrance Room'), lambda state: state.has('Fire Rod') or (state.has('Bombos') and state.has_sword()))
 | 
					    set_rule(world.get_entrance('Ice Palace Entrance Room'), lambda state: state.has('Fire Rod') or (state.has('Bombos') and state.has_sword()))
 | 
				
			||||||
    set_rule(world.get_location('Ice Palace - Big Chest'), lambda state: state.has('Big Key (Ice Palace)'))
 | 
					    set_rule(world.get_location('Ice Palace - Big Chest'), lambda state: state.has('Big Key (Ice Palace)'))
 | 
				
			||||||
    set_rule(world.get_entrance('Ice Palace (Kholdstare)'), lambda state: state.can_lift_rocks() and state.has('Hammer') and state.has('Big Key (Ice Palace)') and (state.has('Small Key (Ice Palace)', 2) or (state.has('Cane of Somaria') and state.has('Small Key (Ice Palace)', 1))))
 | 
					    set_rule(world.get_entrance('Ice Palace (Kholdstare)'), lambda state: state.can_lift_rocks() and state.has('Hammer') and state.has('Big Key (Ice Palace)') and (state.has('Small Key (Ice Palace)', 2) or (state.has('Cane of Somaria') and state.has('Small Key (Ice Palace)', 1))))
 | 
				
			||||||
    set_rule(world.get_entrance('Ice Palace (East)'), lambda state: (state.has('Hookshot') or (item_in_locations(state, 'Big Key (Ice Palace)', ['Ice Palace - Spike Room', 'Ice Palace - Big Key Chest', 'Ice Palace - Map Chest']) and state.has('Small Key (Ice Palace)')) or state.has('Small Key (Ice Palace)', 2)) and (state.has('Hookshot') or state.has('Cape') or state.has('Cane of Byrna')))
 | 
					    set_rule(world.get_entrance('Ice Palace (East)'), lambda state: (state.has('Hookshot') or (item_in_locations(state, 'Big Key (Ice Palace)', ['Ice Palace - Spike Room', 'Ice Palace - Big Key Chest', 'Ice Palace - Map Chest']) and state.has('Small Key (Ice Palace)')) or state.has('Small Key (Ice Palace)', 2)) and (world.can_take_damage or state.has('Hookshot') or state.has('Cape') or state.has('Cane of Byrna')))
 | 
				
			||||||
    set_rule(world.get_entrance('Ice Palace (East Top)'), lambda state: state.can_lift_rocks() and state.has('Hammer'))
 | 
					    set_rule(world.get_entrance('Ice Palace (East Top)'), lambda state: state.can_lift_rocks() and state.has('Hammer'))
 | 
				
			||||||
    for location in ['Ice Palace - Big Chest', 'Ice Palace - Kholdstare']:
 | 
					    for location in ['Ice Palace - Big Chest', 'Ice Palace - Kholdstare']:
 | 
				
			||||||
        forbid_item(world.get_location(location), 'Big Key (Ice Palace)')
 | 
					        forbid_item(world.get_location(location), 'Big Key (Ice Palace)')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_rule(world.get_entrance('Misery Mire Entrance Gap'), lambda state: (state.has_Boots() or state.has('Hookshot')) and (state.has_sword() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Hammer') or state.has('Cane of Somaria') or state.has('Bow')))  # need to defeat wizzrobes, bombs don't work ...
 | 
					    set_rule(world.get_entrance('Misery Mire Entrance Gap'), lambda state: (state.has_Boots() or state.has('Hookshot')) and (state.has_sword() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Hammer') or state.has('Cane of Somaria') or state.has('Bow')))  # need to defeat wizzrobes, bombs don't work ...
 | 
				
			||||||
    set_rule(world.get_location('Misery Mire - Big Chest'), lambda state: state.has('Big Key (Misery Mire)'))
 | 
					    set_rule(world.get_location('Misery Mire - Big Chest'), lambda state: state.has('Big Key (Misery Mire)'))
 | 
				
			||||||
    set_rule(world.get_location('Misery Mire - Spike Chest'), lambda state: state.has('Cane of Byrna') or state.has('Cape'))
 | 
					    set_rule(world.get_location('Misery Mire - Spike Chest'), lambda state: world.can_take_damage or state.has('Cane of Byrna') or state.has('Cape'))
 | 
				
			||||||
    set_rule(world.get_entrance('Misery Mire Big Key Door'), lambda state: state.has('Big Key (Misery Mire)'))
 | 
					    set_rule(world.get_entrance('Misery Mire Big Key Door'), lambda state: state.has('Big Key (Misery Mire)'))
 | 
				
			||||||
    # you can squander the free small key from the pot by opening the south door to the north west switch room, locking you out of accessing a color switch ...
 | 
					    # you can squander the free small key from the pot by opening the south door to the north west switch room, locking you out of accessing a color switch ...
 | 
				
			||||||
    # big key gives backdoor access to that from the teleporter in the north west
 | 
					    # big key gives backdoor access to that from the teleporter in the north west
 | 
				
			||||||
| 
						 | 
					@ -265,8 +277,8 @@ def global_rules(world):
 | 
				
			||||||
    # in addition, you can open the door to the map room before getting access to a color switch, so this is locked behing 2 small keys or the big key...
 | 
					    # in addition, you can open the door to the map room before getting access to a color switch, so this is locked behing 2 small keys or the big key...
 | 
				
			||||||
    set_rule(world.get_location('Misery Mire - Main Lobby'), lambda state: state.has('Small Key (Misery Mire)', 2) or state.has('Big Key (Misery Mire)'))
 | 
					    set_rule(world.get_location('Misery Mire - Main Lobby'), lambda state: state.has('Small Key (Misery Mire)', 2) or state.has('Big Key (Misery Mire)'))
 | 
				
			||||||
    # we can place a small key in the West wing iff it also contains/blocks the Big Key, as we cannot reach and softlock with the basement key door yet
 | 
					    # we can place a small key in the West wing iff it also contains/blocks the Big Key, as we cannot reach and softlock with the basement key door yet
 | 
				
			||||||
    set_rule(world.get_entrance('Misery Mire (West)'), lambda state: state.has('Small Key (Misery Mire)', 2) if ((state.world.get_location('Misery Mire - Compass Chest').item is not None and state.world.get_location('Misery Mire - Compass Chest').item.name in ['Big Key (Misery Mire)']) or
 | 
					    set_rule(world.get_entrance('Misery Mire (West)'), lambda state: state.has('Small Key (Misery Mire)', 2) if ((item_name(state.world.get_location('Misery Mire - Compass Chest')) in ['Big Key (Misery Mire)']) or
 | 
				
			||||||
                                                                                                                 (state.world.get_location('Misery Mire - Big Key Chest').item is not None and state.world.get_location('Misery Mire - Big Key Chest').item.name in ['Big Key (Misery Mire)'])) else state.has('Small Key (Misery Mire)', 3))
 | 
					                                                                                                                 (item_name(state.world.get_location('Misery Mire - Big Key Chest')) in ['Big Key (Misery Mire)'])) else state.has('Small Key (Misery Mire)', 3))
 | 
				
			||||||
    set_rule(world.get_location('Misery Mire - Compass Chest'), lambda state: state.has_fire_source())
 | 
					    set_rule(world.get_location('Misery Mire - Compass Chest'), lambda state: state.has_fire_source())
 | 
				
			||||||
    set_rule(world.get_location('Misery Mire - Big Key Chest'), lambda state: state.has_fire_source())
 | 
					    set_rule(world.get_location('Misery Mire - Big Key Chest'), lambda state: state.has_fire_source())
 | 
				
			||||||
    set_rule(world.get_entrance('Misery Mire (Vitreous)'), lambda state: state.has('Cane of Somaria') and (state.has('Bow') or state.has_blunt_weapon()))
 | 
					    set_rule(world.get_entrance('Misery Mire (Vitreous)'), lambda state: state.has('Cane of Somaria') and (state.has('Bow') or state.has_blunt_weapon()))
 | 
				
			||||||
| 
						 | 
					@ -284,29 +296,31 @@ def global_rules(world):
 | 
				
			||||||
    set_rule(world.get_entrance('Turtle Rock Dark Room Staircase'), lambda state: state.has('Small Key (Turtle Rock)', 3))
 | 
					    set_rule(world.get_entrance('Turtle Rock Dark Room Staircase'), lambda state: state.has('Small Key (Turtle Rock)', 3))
 | 
				
			||||||
    set_rule(world.get_entrance('Turtle Rock (Dark Room) (North)'), lambda state: state.has('Cane of Somaria'))
 | 
					    set_rule(world.get_entrance('Turtle Rock (Dark Room) (North)'), lambda state: state.has('Cane of Somaria'))
 | 
				
			||||||
    set_rule(world.get_entrance('Turtle Rock (Dark Room) (South)'), lambda state: state.has('Cane of Somaria'))
 | 
					    set_rule(world.get_entrance('Turtle Rock (Dark Room) (South)'), lambda state: state.has('Cane of Somaria'))
 | 
				
			||||||
 | 
					    # FIXME: should shield overflow count check to the progrssive logic stuff, so we don't get false mirror shields which would cause problems here
 | 
				
			||||||
    set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Left'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
					    set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Left'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
				
			||||||
    set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Right'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
					    set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Right'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
				
			||||||
    set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Left'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
					    set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Left'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
				
			||||||
    set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Right'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
					    set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Right'), lambda state: state.has('Cane of Byrna') or state.has('Cape') or state.has('Mirror Shield'))
 | 
				
			||||||
    set_rule(world.get_entrance('Turtle Rock (Trinexx)'), lambda state: state.has('Small Key (Turtle Rock)', 4) and state.has('Big Key (Turtle Rock)') and state.has('Cane of Somaria') and state.has('Fire Rod') and state.has('Ice Rod') and
 | 
					    set_rule(world.get_entrance('Turtle Rock (Trinexx)'), lambda state: state.has('Small Key (Turtle Rock)', 4) and state.has('Big Key (Turtle Rock)') and state.has('Cane of Somaria') and state.has('Fire Rod') and state.has('Ice Rod') and
 | 
				
			||||||
             (state.has('Hammer') or state.has_beam_sword() or state.has_bottle() or state.has('Half Magic') or state.has('Quarter Magic')))
 | 
					             (state.has('Hammer') or state.has_beam_sword() or state.can_extend_magic()))
 | 
				
			||||||
 | 
					    # TODO: Per VT, possibly allow a regular sword with 4x extended magic (ie. quater magic, or half magic+bottle or 3 bottles)
 | 
				
			||||||
    set_trock_key_rules(world)
 | 
					    set_trock_key_rules(world)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_rule(world.get_entrance('Palace of Darkness Bonk Wall'), lambda state: state.has('Bow'))
 | 
					    set_rule(world.get_entrance('Palace of Darkness Bonk Wall'), lambda state: state.has('Bow'))
 | 
				
			||||||
    set_rule(world.get_entrance('Palace of Darkness Hammer Peg Drop'), lambda state: state.has('Hammer'))
 | 
					    set_rule(world.get_entrance('Palace of Darkness Hammer Peg Drop'), lambda state: state.has('Hammer'))
 | 
				
			||||||
    set_rule(world.get_entrance('Palace of Darkness Bridge Room'), lambda state: state.has('Small Key (Palace of Darkness)', 1))  # If we can reach any other small key door, we already have back door access to this area
 | 
					    set_rule(world.get_entrance('Palace of Darkness Bridge Room'), lambda state: state.has('Small Key (Palace of Darkness)', 1))  # If we can reach any other small key door, we already have back door access to this area
 | 
				
			||||||
    set_rule(world.get_entrance('Palace of Darkness Big Key Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) and state.has('Big Key (Palace of Darkness)') and state.has('Bow') and state.has('Hammer'))
 | 
					    set_rule(world.get_entrance('Palace of Darkness Big Key Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) and state.has('Big Key (Palace of Darkness)') and state.has('Bow') and state.has('Hammer'))
 | 
				
			||||||
    set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 5)  or (state.world.get_location('Palace of Darkness - Big Key Chest').item is not None and (state.world.get_location('Palace of Darkness - Big Key Chest').item.name in ['Small Key (Palace of Darkness)'])))
 | 
					    set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 5)  or (item_name(state.world.get_location('Palace of Darkness - Big Key Chest')) in ['Small Key (Palace of Darkness)']))
 | 
				
			||||||
    set_rule(world.get_entrance('Palace of Darkness (North)'), lambda state: state.has('Small Key (Palace of Darkness)', 4))
 | 
					    set_rule(world.get_entrance('Palace of Darkness (North)'), lambda state: state.has('Small Key (Palace of Darkness)', 4))
 | 
				
			||||||
    set_rule(world.get_location('Palace of Darkness - Big Chest'), lambda state: state.has('Big Key (Palace of Darkness)'))
 | 
					    set_rule(world.get_location('Palace of Darkness - Big Chest'), lambda state: state.has('Big Key (Palace of Darkness)'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if world.keysanity:
 | 
					    if world.keysanity:
 | 
				
			||||||
        set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) or (state.world.get_location('Palace of Darkness - Harmless Hellway').item is not None and (state.world.get_location('Palace of Darkness - Harmless Hellway').item.name in ['Small Key (Palace of Darkness)'])))
 | 
					        set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6) or (item_name(state.world.get_location('Palace of Darkness - Harmless Hellway')) in ['Small Key (Palace of Darkness)']))
 | 
				
			||||||
        set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 6)  or (state.world.get_location('Palace of Darkness - Big Key Chest').item is not None and (state.world.get_location('Palace of Darkness - Big Key Chest').item.name in ['Small Key (Palace of Darkness)'])))
 | 
					        set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 6)  or (item_name(state.world.get_location('Palace of Darkness - Big Key Chest')) in ['Small Key (Palace of Darkness)']))
 | 
				
			||||||
        set_rule(world.get_entrance('Palace of Darkness Maze Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6))
 | 
					        set_rule(world.get_entrance('Palace of Darkness Maze Door'), lambda state: state.has('Small Key (Palace of Darkness)', 6))
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 5) or (state.world.get_location('Palace of Darkness - Harmless Hellway').item is not None and (state.world.get_location('Palace of Darkness - Harmless Hellway').item.name in ['Small Key (Palace of Darkness)'])))
 | 
					        set_rule(world.get_entrance('Palace of Darkness Spike Statue Room Door'), lambda state: state.has('Small Key (Palace of Darkness)', 5) or (item_name(state.world.get_location('Palace of Darkness - Harmless Hellway')) in ['Small Key (Palace of Darkness)']))
 | 
				
			||||||
        set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 5)  or (state.world.get_location('Palace of Darkness - Big Key Chest').item is not None and (state.world.get_location('Palace of Darkness - Big Key Chest').item.name in ['Small Key (Palace of Darkness)'])))
 | 
					        set_rule(world.get_entrance('Palace of Darkness Big Key Chest Staircase'), lambda state: state.has('Small Key (Palace of Darkness)', 5)  or (item_name(state.world.get_location('Palace of Darkness - Big Key Chest')) in ['Small Key (Palace of Darkness)']))
 | 
				
			||||||
        set_rule(world.get_entrance('Palace of Darkness Maze Door'), lambda state: state.has('Small Key (Palace of Darkness)', 5))
 | 
					        set_rule(world.get_entrance('Palace of Darkness Maze Door'), lambda state: state.has('Small Key (Palace of Darkness)', 5))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Helmasaur']:
 | 
					    for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Helmasaur']:
 | 
				
			||||||
| 
						 | 
					@ -322,13 +336,12 @@ def global_rules(world):
 | 
				
			||||||
    set_rule(world.get_location('Ganons Tower - Bob\'s Torch'), lambda state: state.has_Boots())
 | 
					    set_rule(world.get_location('Ganons Tower - Bob\'s Torch'), lambda state: state.has_Boots())
 | 
				
			||||||
    set_rule(world.get_entrance('Ganons Tower (Tile Room)'), lambda state: state.has('Cane of Somaria'))
 | 
					    set_rule(world.get_entrance('Ganons Tower (Tile Room)'), lambda state: state.has('Cane of Somaria'))
 | 
				
			||||||
    set_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hammer'))
 | 
					    set_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hammer'))
 | 
				
			||||||
    if world.keysanity:
 | 
					 | 
				
			||||||
        set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.has('Small Key (Ganons Tower)', 4) or (state.world.get_location('Ganons Tower - Map Chest').item is not None and state.world.get_location('Ganons Tower - Map Chest').item.name == 'Big Key (Ganons Tower)' and state.has('Small Key (Ganons Tower)', 3)) or (state.world.get_location('Ganons Tower - Map Chest').item is not None and state.world.get_location('Ganons Tower - Map Chest').item.name == 'Small Key (Ganons Tower)'))
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3) or (state.world.get_location('Ganons Tower - Map Chest').item is not None and state.world.get_location('Ganons Tower - Map Chest').item.name == 'Small Key (Ganons Tower)'))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # It is possible to need more than 2 keys to get through this entance if you spend keys elsewhere We reflect this in the chest requirements.
 | 
					    set_rule(world.get_entrance('Ganons Tower (Map Room)'), lambda state: state.has('Small Key (Ganons Tower)', 4) or (item_name(state.world.get_location('Ganons Tower - Map Chest')) in ['Big Key (Ganons Tower)', 'Small Key (Ganons Tower)'] and state.has('Small Key (Ganons Tower)', 3)))
 | 
				
			||||||
    # However we need to leave these at the lower values derive that with 3 keys it is always possible to reach Bob and Ice Armos.
 | 
					    set_always_allow(world.get_entrance('Ganons Tower (Map Room)'), lambda state, item: item.name == 'Small Key (Ganons Tower)' and state.has('Small Key (Ganons Tower)', 3))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # It is possible to need more than 2 keys to get through this entance if you spend keys elsewhere. We reflect this in the chest requirements.
 | 
				
			||||||
 | 
					    # However we need to leave these at the lower values to derive that with 3 keys it is always possible to reach Bob and Ice Armos.
 | 
				
			||||||
    set_rule(world.get_entrance('Ganons Tower (Double Switch Room)'), lambda state: state.has('Small Key (Ganons Tower)', 2))
 | 
					    set_rule(world.get_entrance('Ganons Tower (Double Switch Room)'), lambda state: state.has('Small Key (Ganons Tower)', 2))
 | 
				
			||||||
    # It is possible to need more than 3 keys ....
 | 
					    # It is possible to need more than 3 keys ....
 | 
				
			||||||
    set_rule(world.get_entrance('Ganons Tower (Firesnake Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3))
 | 
					    set_rule(world.get_entrance('Ganons Tower (Firesnake Room)'), lambda state: state.has('Small Key (Ganons Tower)', 3))
 | 
				
			||||||
| 
						 | 
					@ -361,7 +374,7 @@ def global_rules(world):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_rule(world.get_location('Ganon'), lambda state: state.has_beam_sword() and state.has_fire_source() and state.has('Crystal 1') and state.has('Crystal 2')
 | 
					    set_rule(world.get_location('Ganon'), lambda state: state.has_beam_sword() and state.has_fire_source() and state.has('Crystal 1') and state.has('Crystal 2')
 | 
				
			||||||
                                                        and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7')
 | 
					                                                        and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7')
 | 
				
			||||||
                                                        and (state.has('Tempered Sword') or state.has('Golden Sword') or (state.has('Silver Arrows') and state.has('Bow')) or state.has('Lamp') or state.has_bottle() or state.has('Half Magic') or state.has('Quarter Magic')))  # need to light torch a sufficient amount of times
 | 
					                                                        and (state.has('Tempered Sword') or state.has('Golden Sword') or (state.has('Silver Arrows') and state.has('Bow')) or state.has('Lamp') or state.can_extend_magic()))  # need to light torch a sufficient amount of times
 | 
				
			||||||
    set_rule(world.get_entrance('Ganon Drop'), lambda state: state.has_beam_sword())  # need to damage ganon to get tiles to drop
 | 
					    set_rule(world.get_entrance('Ganon Drop'), lambda state: state.has_beam_sword())  # need to damage ganon to get tiles to drop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -426,11 +439,8 @@ def open_rules(world):
 | 
				
			||||||
    forbid_item(world.get_location('Hyrule Castle - Boomerang Chest'), 'Small Key (Escape)')
 | 
					    forbid_item(world.get_location('Hyrule Castle - Boomerang Chest'), 'Small Key (Escape)')
 | 
				
			||||||
    forbid_item(world.get_location('Hyrule Castle - Zelda\'s Chest'), 'Small Key (Escape)')
 | 
					    forbid_item(world.get_location('Hyrule Castle - Zelda\'s Chest'), 'Small Key (Escape)')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # to prevent key-lock in keysanity we need to prevent these chests from having an item that
 | 
					    set_rule(world.get_location('Hyrule Castle - Boomerang Chest'), lambda state: state.has('Small Key (Escape)'))
 | 
				
			||||||
    # blocks the small key
 | 
					    set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest'), lambda state: state.has('Small Key (Escape)'))
 | 
				
			||||||
    if world.keysanity:
 | 
					 | 
				
			||||||
        set_rule(world.get_location('Hyrule Castle - Boomerang Chest'), lambda state: state.has('Small Key (Escape)'))
 | 
					 | 
				
			||||||
        set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest'), lambda state: state.has('Small Key (Escape)'))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def swordless_rules(world):
 | 
					def swordless_rules(world):
 | 
				
			||||||
| 
						 | 
					@ -455,10 +465,13 @@ def swordless_rules(world):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def standard_rules(world):
 | 
					def standard_rules(world):
 | 
				
			||||||
    # easiest way to enforce key placement not relevant for open
 | 
					    # easiest way to enforce key placement not relevant for open
 | 
				
			||||||
    forbid_item(world.get_location('Sewers - Secret Room - Left'), 'Small Key (Escape)')
 | 
					    set_rule(world.get_location('Sewers - Dark Cross'), lambda state: state.can_kill_most_things())
 | 
				
			||||||
    forbid_item(world.get_location('Sewers - Secret Room - Middle'), 'Small Key (Escape)')
 | 
					    add_rule(world.get_entrance('Sewers Door'), lambda state: state.can_kill_most_things())
 | 
				
			||||||
    forbid_item(world.get_location('Sewers - Secret Room - Right'), 'Small Key (Escape)')
 | 
					
 | 
				
			||||||
    forbid_item(world.get_location('Sanctuary'), 'Small Key (Escape)')
 | 
					    set_rule(world.get_location('Hyrule Castle - Boomerang Chest'), lambda state: state.can_kill_most_things())
 | 
				
			||||||
 | 
					    set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest'), lambda state: state.can_kill_most_things())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def set_trock_key_rules(world):
 | 
					def set_trock_key_rules(world):
 | 
				
			||||||
| 
						 | 
					@ -495,11 +508,12 @@ def set_trock_key_rules(world):
 | 
				
			||||||
    # however in keysanity being able to reach all other chests while only having three keys does not imply this contains
 | 
					    # however in keysanity being able to reach all other chests while only having three keys does not imply this contains
 | 
				
			||||||
    # a key, so we again need all four keys unless it contains the big key
 | 
					    # a key, so we again need all four keys unless it contains the big key
 | 
				
			||||||
    if can_reach_back:
 | 
					    if can_reach_back:
 | 
				
			||||||
        set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 4) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))
 | 
					        set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 4) or (item_name(state.world.get_location('Turtle Rock - Big Key Chest')) in ['Small Key (Turtle Rock)']))
 | 
				
			||||||
    elif world.keysanity:
 | 
					    elif world.keysanity:
 | 
				
			||||||
        set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 2) if (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Big Key (Turtle Rock)'])) else state.has('Small Key (Turtle Rock)', 4) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))
 | 
					        set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 2) if (item_name(state.world.get_location('Turtle Rock - Big Key Chest')) in ['Big Key (Turtle Rock)']) else state.has('Small Key (Turtle Rock)', 4) or (item_name(state.world.get_location('Turtle Rock - Big Key Chest')) in ['Small Key (Turtle Rock)']))
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 2) if (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Big Key (Turtle Rock)'])) else state.has('Small Key (Turtle Rock)', 3) or (state.world.get_location('Turtle Rock - Big Key Chest').item is not None and (state.world.get_location('Turtle Rock - Big Key Chest').item.name in ['Small Key (Turtle Rock)'])))
 | 
					        set_rule(world.get_location('Turtle Rock - Big Key Chest'), lambda state: state.has('Small Key (Turtle Rock)', 2) if (item_name(state.world.get_location('Turtle Rock - Big Key Chest')) in ['Big Key (Turtle Rock)']) else state.has('Small Key (Turtle Rock)', 3) or (item_name(state.world.get_location('Turtle Rock - Big Key Chest')) in ['Small Key (Turtle Rock)']))
 | 
				
			||||||
 | 
					    # FIXME add key-for-key logic to the above mess via always_allow rules. Ugh!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # set big key restrictions
 | 
					    # set big key restrictions
 | 
				
			||||||
    non_big_key_locations = ['Turtle Rock - Big Chest', 'Turtle Rock - Trinexx']
 | 
					    non_big_key_locations = ['Turtle Rock - Big Chest', 'Turtle Rock - Trinexx']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue