first pass at owg logic support
This commit is contained in:
		
							parent
							
								
									636a18cee9
								
							
						
					
					
						commit
						c09fab64f8
					
				| 
						 | 
				
			
			@ -28,14 +28,17 @@ def parse_arguments(argv, no_defaults=False):
 | 
			
		|||
 | 
			
		||||
    parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
 | 
			
		||||
    parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true')
 | 
			
		||||
    parser.add_argument('--logic', default=defval('noglitches'), const='noglitches', nargs='?', choices=['noglitches', 'minorglitches', 'nologic'],
 | 
			
		||||
    parser.add_argument('--logic', default=defval('noglitches'), const='noglitches', nargs='?', choices=['noglitches', 'minorglitches', 'owglitches', 'nologic'],
 | 
			
		||||
                        help='''\
 | 
			
		||||
                             Select Enforcement of Item Requirements. (default: %(default)s)
 | 
			
		||||
                             No Glitches:
 | 
			
		||||
                             Minor Glitches: May require Fake Flippers, Bunny Revival
 | 
			
		||||
                                             and Dark Room Navigation.
 | 
			
		||||
                             Overworld Glitches: May require overworld glitches. Starts with
 | 
			
		||||
                                             boots.
 | 
			
		||||
                             No Logic: Distribute items without regard for
 | 
			
		||||
                                             item requirements.
 | 
			
		||||
                                             item requirements. Starts with
 | 
			
		||||
                                             boots
 | 
			
		||||
                             ''')
 | 
			
		||||
    parser.add_argument('--mode', default=defval('open'), const='open', nargs='?', choices=['standard', 'open', 'inverted'],
 | 
			
		||||
                        help='''\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2987,7 +2987,8 @@ mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central
 | 
			
		|||
                         ('Pyramid Drop', 'East Dark World')
 | 
			
		||||
                        ]
 | 
			
		||||
 | 
			
		||||
inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), 
 | 
			
		||||
inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'),
 | 
			
		||||
                                  ('Lake Hylia Island', 'Lake Hylia Island'),
 | 
			
		||||
                                  ('Zoras River', 'Zoras River'), 
 | 
			
		||||
                                  ('Kings Grave Outer Rocks', 'Kings Grave Area'),
 | 
			
		||||
                                  ('Kings Grave Inner Rocks', 'Light World'),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								Gui.py
								
								
								
								
							
							
						
						
									
										2
									
								
								Gui.py
								
								
								
								
							| 
						 | 
				
			
			@ -193,7 +193,7 @@ def guiMain(args=None):
 | 
			
		|||
    logicFrame = Frame(drowDownFrame)
 | 
			
		||||
    logicVar = StringVar()
 | 
			
		||||
    logicVar.set('noglitches')
 | 
			
		||||
    logicOptionMenu = OptionMenu(logicFrame, logicVar, 'noglitches', 'minorglitches', 'nologic')
 | 
			
		||||
    logicOptionMenu = OptionMenu(logicFrame, logicVar, 'noglitches', 'minorglitches', 'owglitches', 'nologic')
 | 
			
		||||
    logicOptionMenu.pack(side=RIGHT)
 | 
			
		||||
    logicLabel = Label(logicFrame, text='Game logic')
 | 
			
		||||
    logicLabel.pack(side=LEFT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ def create_inverted_regions(world, player):
 | 
			
		|||
                         ["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Kings Grave Outer Rocks', 'Dam',
 | 
			
		||||
                          'Inverted Big Bomb Shop', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave',
 | 
			
		||||
                          'Blacksmiths Hut', 'Bat Cave Drop Ledge', 'Bat Cave Cave', 'Sick Kids House', 'Hobo Bridge', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump',
 | 
			
		||||
                          'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier',
 | 
			
		||||
                          'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier', 'Lake Hylia Island',
 | 
			
		||||
                          'Bonk Rock Cave', 'Library', 'Two Brothers House (East)', 'Desert Palace Stairs', 'Eastern Palace', 'Master Sword Meadow',
 | 
			
		||||
                          'Sanctuary', 'Sanctuary Grave', 'Death Mountain Entrance Rock', 'Light World River Drop',
 | 
			
		||||
                          'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										34
									
								
								ItemList.py
								
								
								
								
							
							
						
						
									
										34
									
								
								ItemList.py
								
								
								
								
							| 
						 | 
				
			
			@ -177,7 +177,7 @@ def generate_itempool(world, player):
 | 
			
		|||
        (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.customitemarray)
 | 
			
		||||
        world.rupoor_cost = min(world.customitemarray[69], 9999)
 | 
			
		||||
    else:
 | 
			
		||||
        (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player])
 | 
			
		||||
        (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.logic[player])
 | 
			
		||||
 | 
			
		||||
    for item in precollected_items:
 | 
			
		||||
        world.push_precollected(ItemFactory(item, player))
 | 
			
		||||
| 
						 | 
				
			
			@ -386,7 +386,7 @@ def set_up_shops(world, player):
 | 
			
		|||
 | 
			
		||||
    #special shop types
 | 
			
		||||
 | 
			
		||||
def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, retro):
 | 
			
		||||
def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, logic):
 | 
			
		||||
    pool = []
 | 
			
		||||
    placed_items = {}
 | 
			
		||||
    precollected_items = []
 | 
			
		||||
| 
						 | 
				
			
			@ -403,6 +403,11 @@ def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, r
 | 
			
		|||
    def want_progressives():
 | 
			
		||||
        return random.choice([True, False]) if progressive == 'random' else progressive == 'on'
 | 
			
		||||
 | 
			
		||||
    # provide boots to major glitch dependent seeds
 | 
			
		||||
    if logic in ['owglitches', 'nologic']:
 | 
			
		||||
        precollected_items.append('Pegasus Boots')
 | 
			
		||||
        pool.remove('Pegasus Boots')
 | 
			
		||||
 | 
			
		||||
    if want_progressives():
 | 
			
		||||
        pool.extend(progressivegloves)
 | 
			
		||||
    else:
 | 
			
		||||
| 
						 | 
				
			
			@ -685,19 +690,20 @@ def test():
 | 
			
		|||
                        for progressive in ['on', 'off']:
 | 
			
		||||
                            for shuffle in ['full', 'insanity_legacy']:
 | 
			
		||||
                                for retro in [True, False]:
 | 
			
		||||
                                    out = get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, retro)
 | 
			
		||||
                                    count = len(out[0]) + len(out[1])
 | 
			
		||||
                                    for logic in ['noglitches', 'owglitches']:
 | 
			
		||||
                                        out = get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, logic)
 | 
			
		||||
                                        count = len(out[0]) + len(out[1])
 | 
			
		||||
 | 
			
		||||
                                    correct_count = total_items_to_place
 | 
			
		||||
                                    if goal == 'pedestal' and swords != 'vanilla':
 | 
			
		||||
                                        # pedestal goals generate one extra item
 | 
			
		||||
                                        correct_count += 1
 | 
			
		||||
                                    if retro:
 | 
			
		||||
                                        correct_count += 28
 | 
			
		||||
                                    try:
 | 
			
		||||
                                        assert count == correct_count, "expected {0} items but found {1} items for {2}".format(correct_count, count, (progressive, shuffle, difficulty, timer, goal, mode, swords, retro))
 | 
			
		||||
                                    except AssertionError as e:
 | 
			
		||||
                                        print(e)
 | 
			
		||||
                                        correct_count = total_items_to_place
 | 
			
		||||
                                        if goal == 'pedestal' and swords != 'vanilla':
 | 
			
		||||
                                            # pedestal goals generate one extra item
 | 
			
		||||
                                            correct_count += 1
 | 
			
		||||
                                        if retro:
 | 
			
		||||
                                            correct_count += 28
 | 
			
		||||
                                        try:
 | 
			
		||||
                                            assert count == correct_count, "expected {0} items but found {1} items for {2}".format(correct_count, count, (progressive, shuffle, difficulty, timer, goal, mode, swords, retro))
 | 
			
		||||
                                        except AssertionError as e:
 | 
			
		||||
                                            print(e)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    test()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,10 +114,10 @@ def roll_settings(weights):
 | 
			
		|||
    ret = argparse.Namespace()
 | 
			
		||||
 | 
			
		||||
    glitches_required = get_choice('glitches_required')
 | 
			
		||||
    if glitches_required not in ['none', 'no_logic']:
 | 
			
		||||
        print("Only NMG and No Logic supported")
 | 
			
		||||
    if glitches_required not in ['none', 'no_logic', 'overworld_glitches']:
 | 
			
		||||
        print("Only NMG, OWG and No Logic supported")
 | 
			
		||||
        glitches_required = 'none'
 | 
			
		||||
    ret.logic = {'none': 'noglitches', 'no_logic': 'nologic'}[glitches_required]
 | 
			
		||||
    ret.logic = {'none': 'noglitches', 'no_logic': 'nologic', 'overworld_glitches': 'owglitches'}[glitches_required]
 | 
			
		||||
 | 
			
		||||
    item_placement = get_choice('item_placement')
 | 
			
		||||
    # not supported in ER
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								Rom.py
								
								
								
								
							
							
						
						
									
										8
									
								
								Rom.py
								
								
								
								
							| 
						 | 
				
			
			@ -901,7 +901,7 @@ def patch_rom(world, player, rom, enemized):
 | 
			
		|||
        rom.write_byte(x, 0) # Zero the initial equipment array
 | 
			
		||||
    rom.write_byte(0x18302C, 0x18) # starting max health
 | 
			
		||||
    rom.write_byte(0x18302D, 0x18) # starting current health
 | 
			
		||||
    rom.write_byte(0x183039, 0x68) # starting abilities, bit array
 | 
			
		||||
    ability_flags = 0x68 # starting abilities, bit array; may be modified by precollected items
 | 
			
		||||
    
 | 
			
		||||
    for item in world.precollected_items:
 | 
			
		||||
        if item.player != player:
 | 
			
		||||
| 
						 | 
				
			
			@ -911,9 +911,15 @@ def patch_rom(world, player, rom, enemized):
 | 
			
		|||
            rom.write_byte(0x183000+0x19, 0x01)
 | 
			
		||||
            rom.write_byte(0x0271A6+0x19, 0x01)
 | 
			
		||||
            rom.write_byte(0x180043, 0x01) # special starting sword byte
 | 
			
		||||
        elif item.name == 'Pegasus Boots':
 | 
			
		||||
            rom.write_byte(0x183015, 0x01)
 | 
			
		||||
            ability_flags |= 0b00000100
 | 
			
		||||
        else:
 | 
			
		||||
            raise RuntimeError("Unsupported pre-collected item: {}".format(item))
 | 
			
		||||
 | 
			
		||||
    # write abilities after ability flags have been determined
 | 
			
		||||
    rom.write_byte(0x183039, ability_flags)
 | 
			
		||||
 | 
			
		||||
    rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01)  # Inverted mode
 | 
			
		||||
    rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier
 | 
			
		||||
    rom.write_byte(0x2AF79, 0xD0 if world.mode[player] != 'inverted' else 0xF0) # vortexes: Normal  (D0=light to dark, F0=dark to light, 42 = both)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										84
									
								
								Rules.py
								
								
								
								
							
							
						
						
									
										84
									
								
								Rules.py
								
								
								
								
							| 
						 | 
				
			
			@ -38,6 +38,8 @@ def set_rules(world, player):
 | 
			
		|||
 | 
			
		||||
    if world.logic[player] == 'noglitches':
 | 
			
		||||
        no_glitches_rules(world, player)
 | 
			
		||||
    elif world.logic[player] == 'owglitches':
 | 
			
		||||
        overworld_glitches_rules(world, player)
 | 
			
		||||
    elif world.logic[player] == 'minorglitches':
 | 
			
		||||
        logging.getLogger('').info('Minor Glitches may be buggy still. No guarantee for proper logic checks.')
 | 
			
		||||
    else:
 | 
			
		||||
| 
						 | 
				
			
			@ -357,7 +359,6 @@ def default_rules(world, player):
 | 
			
		|||
    set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player))
 | 
			
		||||
    # Caution: If king's grave is releaxed at all to account for reaching it via a two way cave's exit in insanity mode, then the bomb shop logic will need to be updated (that would involve create a small ledge-like Region for it)
 | 
			
		||||
    set_rule(world.get_entrance('Bonk Fairy (Light)', player), lambda state: state.has_Boots(player))
 | 
			
		||||
    set_rule(world.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player))
 | 
			
		||||
    set_rule(world.get_entrance('Lumberjack Tree Tree', player), lambda state: state.has_Boots(player) and state.has('Beat Agahnim 1', player))
 | 
			
		||||
    set_rule(world.get_entrance('Bonk Rock Cave', player), lambda state: state.has_Boots(player))
 | 
			
		||||
    set_rule(world.get_entrance('Desert Palace Stairs', player), lambda state: state.has('Book of Mudora', player))
 | 
			
		||||
| 
						 | 
				
			
			@ -625,8 +626,10 @@ def no_glitches_rules(world, player):
 | 
			
		|||
        set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player) and (state.has('Hammer', player) or state.can_lift_rocks(player)))
 | 
			
		||||
        set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
 | 
			
		||||
    else:
 | 
			
		||||
        set_rule(world.get_entrance('Bat Cave Drop Ledge', player), lambda state: state.has('Hammer', player))
 | 
			
		||||
        set_rule(world.get_entrance('Zoras River', player), lambda state: state.has_Pearl(player) and (state.has('Flippers', player) or state.can_lift_rocks(player)))
 | 
			
		||||
        set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))  # can be fake flippered to
 | 
			
		||||
        set_rule(world.get_entrance('Lake Hylia Island', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
 | 
			
		||||
        set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
 | 
			
		||||
        set_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player))
 | 
			
		||||
        set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player) and (state.has('Hammer', player) or state.can_lift_rocks(player)))
 | 
			
		||||
| 
						 | 
				
			
			@ -641,7 +644,10 @@ def no_glitches_rules(world, player):
 | 
			
		|||
    set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False)  # no glitches does not require block override
 | 
			
		||||
    set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False)
 | 
			
		||||
    set_rule(world.get_entrance('Skull Woods First Section Bomb Jump', player), lambda state: False)
 | 
			
		||||
    add_conditional_lamps(world, player)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def add_conditional_lamps(world, player):
 | 
			
		||||
    # Light cones in standard depend on which world we actually are in, not which one the location would normally be
 | 
			
		||||
    # We add Lamp requirements only to those locations which lie in the dark world (or everything if open
 | 
			
		||||
    DW_Entrances = ['Bumper Cave (Bottom)', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', 'Dark Death Mountain Ledge (East)',
 | 
			
		||||
| 
						 | 
				
			
			@ -690,6 +696,82 @@ def no_glitches_rules(world, player):
 | 
			
		|||
        add_lamp_requirement(world.get_entrance('Throne Room', player), player)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def overworld_glitches_rules(world, player):
 | 
			
		||||
    # spots that are immediately accessible
 | 
			
		||||
    set_rule(world.get_entrance('Hobo Bridge', player), lambda state: True)
 | 
			
		||||
    set_rule(world.get_region('Lake Hylia Central Island', player), lambda state: True)
 | 
			
		||||
    set_rule(world.get_entrance('Zoras River', player), lambda state: True)
 | 
			
		||||
    # lw boots-accessible locations
 | 
			
		||||
    lw_boots_accessible_regions = [
 | 
			
		||||
        'Bat Cave Drop Ledge',
 | 
			
		||||
        'Lake Hylia Island',
 | 
			
		||||
        'Desert Ledge',
 | 
			
		||||
        'Desert Ledge (Northeast)',
 | 
			
		||||
        'Desert Palace Lone Stairs',
 | 
			
		||||
        'Desert Palace Entrance (North) Spot',
 | 
			
		||||
        'Death Mountain',
 | 
			
		||||
        'Death Mountain Return Ledge',
 | 
			
		||||
        'East Death Mountain (Bottom)',
 | 
			
		||||
        'East Death Mountain (Top)',
 | 
			
		||||
        'Death Mountain (Top)',
 | 
			
		||||
        'Spectacle Rock',
 | 
			
		||||
        'Death Mountain Floating Island (Light World)',
 | 
			
		||||
    ]
 | 
			
		||||
    # dw boots-accessible regions
 | 
			
		||||
    dw_boots_accessible_regions = [
 | 
			
		||||
        'East Dark World',
 | 
			
		||||
        'Northeast Dark World',
 | 
			
		||||
        'West Dark World',
 | 
			
		||||
        'Hammer Peg Area',
 | 
			
		||||
        'Bumper Cave Ledge',
 | 
			
		||||
        'Dark Desert',
 | 
			
		||||
        'Dark Death Mountain (Top)',
 | 
			
		||||
        'Dark Death Mountain (East Bottom)',
 | 
			
		||||
        'Dark Death Mountain Ledge',
 | 
			
		||||
        'Death Mountain Floating Island (Dark World)',
 | 
			
		||||
        'Turtle Rock (Top)',
 | 
			
		||||
    ]
 | 
			
		||||
    # set up boots-accessible regions
 | 
			
		||||
    if world.mode[player] != 'inverted':
 | 
			
		||||
        lw_boots_accessible_regions.append('Cave 45 Ledge')
 | 
			
		||||
        lw_boots_accessible_regions.append('Graveyard Ledge')
 | 
			
		||||
        # couple other random spots
 | 
			
		||||
        set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player) and (state.has_Mirror(player) or state.has_Boots(player)))
 | 
			
		||||
        set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: (state.has('Ocarina', player) or state.has_Boots(player)) and state.can_lift_heavy_rocks(player))
 | 
			
		||||
        set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: (state.has('Hammer', player) or state.has_Boots(player)) and state.can_lift_rocks(player))
 | 
			
		||||
        set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player))
 | 
			
		||||
        add_rule(world.get_entrance('Ganons Tower', player), lambda state: state.has_Boots(player) and state.has_Pearl(player), 'or')
 | 
			
		||||
    needs_boots = lambda state: state.has_Boots(player)
 | 
			
		||||
    needs_boots_and_pearl = lambda state: state.has_Boots(player) and state.has_Pearl(player)
 | 
			
		||||
    for spot in lw_boots_accessible_regions:
 | 
			
		||||
        for location in world.get_region(spot, player).locations:
 | 
			
		||||
            add_rule(world.get_location(location, player), needs_boots_and_pearl if world.mode[player] == 'inverted' else needs_boots, 'or')
 | 
			
		||||
    for spot in dw_boots_accessible_regions:
 | 
			
		||||
        for location in world.get_region(spot, player).locations:
 | 
			
		||||
            add_rule(world.get_location(location, player), needs_boots if world.mode[player] == 'inverted' else needs_boots_and_pearl, 'or')
 | 
			
		||||
    # bunny DMD rules
 | 
			
		||||
    if world.mode[player] != 'inverted':
 | 
			
		||||
        # set up some mirror-accessible dw entrances.
 | 
			
		||||
        boots_and_mirror = lambda state: state.has_Boots(player) and state.has_Mirror(player)
 | 
			
		||||
        add_rule(world.get_entrance('Dark Sanctuary Hint', player), boots_and_mirror, 'or') # should suffice to give us west dark world access
 | 
			
		||||
        for spot in world.get_region('Dark Death Mountain (East Bottom)', player).locations:
 | 
			
		||||
            add_rule(world.get_location(spot, player), boots_and_mirror, 'or')
 | 
			
		||||
        # dw entrances accessible with mirror and hookshot
 | 
			
		||||
        mirror_hookshot_accessible_dw_locations = [
 | 
			
		||||
            'Pyramid Fairy',
 | 
			
		||||
            'Pyramid Entrance',
 | 
			
		||||
            'Pyramid Drop',
 | 
			
		||||
        ]
 | 
			
		||||
        mirror_hookshot_accessible_dw_locations.extend(world.get_region('Dark Death Mountain Ledge', player).locations)
 | 
			
		||||
        for spot in mirror_hookshot_accessible_dw_locations:
 | 
			
		||||
            add_rule(world.get_entrance(spot, player), lambda state: state.has_Boots(player) and state.has_Mirror(player) and state.has('Hookshot', player), 'or')
 | 
			
		||||
        # dw entrances accessible with mirror and titans
 | 
			
		||||
        boots_mirror_titans = lambda state: state.has_Boots(player) and state.has_Mirror(player) and state.can_lift_heavy_rocks(player)
 | 
			
		||||
        add_rule(world.get_entrance('Mire Shed', player), boots_mirror_titans, 'or')
 | 
			
		||||
        add_rule(world.get_location('Frog', player), boots_mirror_titans, 'or')
 | 
			
		||||
    add_conditional_lamps(world, player)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def open_rules(world, player):
 | 
			
		||||
    # softlock protection as you can reach the sewers small key door with a guard drop key
 | 
			
		||||
    set_rule(world.get_location('Hyrule Castle - Boomerang Chest', player), lambda state: state.has_key('Small Key (Escape)', player))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue