Whitespace fixes

This commit is contained in:
Kevin Cathcart 2017-11-04 14:23:57 -04:00
parent cdf04b8a45
commit 5b3d4449c1
10 changed files with 85 additions and 83 deletions

View File

@ -96,7 +96,7 @@ class World(object):
def get_all_state(self, keys=False): def get_all_state(self, keys=False):
ret = CollectionState(self) ret = CollectionState(self)
def soft_collect(item): def soft_collect(item):
if item.name.startswith('Progressive '): if item.name.startswith('Progressive '):
if 'Sword' in item.name: if 'Sword' in item.name:

View File

@ -13,6 +13,7 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
def _get_help_string(self, action): def _get_help_string(self, action):
return textwrap.dedent(action.help) return textwrap.dedent(action.help)
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true') parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true')

View File

@ -668,7 +668,7 @@ def connect_entrance(world, entrancename, exitname):
# if this was already connected somewhere, remove the backreference # if this was already connected somewhere, remove the backreference
if entrance.connected_region is not None: if entrance.connected_region is not None:
entrance.connected_region.entrances.remove(entrance) entrance.connected_region.entrances.remove(entrance)
target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None) target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None)
addresses = door_addresses[entrance.name][0][0] if exit is not None else door_addresses[entrance.name][0] addresses = door_addresses[entrance.name][0][0] if exit is not None else door_addresses[entrance.name][0]
try: try:
@ -676,7 +676,7 @@ def connect_entrance(world, entrancename, exitname):
vanilla = exit_ids[vanilla_ref] vanilla = exit_ids[vanilla_ref]
except IndexError: except IndexError:
vanilla = None vanilla = None
entrance.connect(region, addresses, target, vanilla) entrance.connect(region, addresses, target, vanilla)
world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance') world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance')

View File

@ -1,6 +1,7 @@
import random import random
import logging import logging
def distribute_items_cutoff(world, cutoffrate=0.33): def distribute_items_cutoff(world, cutoffrate=0.33):
# get list of locations to fill in # get list of locations to fill in
fill_locations = world.get_unfilled_locations() fill_locations = world.get_unfilled_locations()
@ -55,7 +56,7 @@ def distribute_items_cutoff(world, cutoffrate=0.33):
raise RuntimeError('No more progress items left to place.') raise RuntimeError('No more progress items left to place.')
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 world.state.can_reach(location) and location.can_fill(item_to_place):
spot_to_fill = location spot_to_fill = location
break break
@ -199,7 +200,7 @@ def fill_restrictive(world, base_state, locations, itempool):
spot_to_fill.event = True spot_to_fill.event = True
def distribute_items_restrictive(world, gftower_trash_count=0,fill_locations=None): def distribute_items_restrictive(world, gftower_trash_count=0, fill_locations=None):
# If not passed in, then get a shuffled list of locations to fill in # If not passed in, then get a shuffled list of locations to fill in
if not fill_locations: if not fill_locations:
fill_locations = world.get_unfilled_locations() fill_locations = world.get_unfilled_locations()
@ -223,7 +224,7 @@ def distribute_items_restrictive(world, gftower_trash_count=0,fill_locations=Non
trashcnt += 1 trashcnt += 1
random.shuffle(fill_locations) random.shuffle(fill_locations)
fill_locations.reverse() fill_locations.reverse()
fill_restrictive(world, world.state, fill_locations, progitempool) fill_restrictive(world, world.state, fill_locations, progitempool)
@ -242,7 +243,7 @@ def fast_fill(world, item_pool, fill_locations):
item_to_place = item_pool.pop() item_to_place = item_pool.pop()
world.push_item(spot_to_fill, item_to_place, False) world.push_item(spot_to_fill, item_to_place, False)
def flood_items(world): def flood_items(world):
# get items to distribute # get items to distribute
random.shuffle(world.itempool) random.shuffle(world.itempool)

21
Gui.py
View File

@ -38,18 +38,19 @@ def guiMain(args=None):
dungeonItemsCheckbutton.pack(expand=True, anchor=W) dungeonItemsCheckbutton.pack(expand=True, anchor=W)
beatableOnlyCheckbutton.pack(expand=True, anchor=W) beatableOnlyCheckbutton.pack(expand=True, anchor=W)
shuffleGanonCheckbutton.pack(expand=True, anchor=W) shuffleGanonCheckbutton.pack(expand=True, anchor=W)
fileDialogFrame = Frame(rightHalfFrame) fileDialogFrame = Frame(rightHalfFrame)
romDialogFrame = Frame(fileDialogFrame) romDialogFrame = Frame(fileDialogFrame)
baseRomLabel = Label(romDialogFrame, text='Base Rom') baseRomLabel = Label(romDialogFrame, text='Base Rom')
romVar = StringVar() romVar = StringVar()
romEntry = Entry(romDialogFrame, textvariable=romVar) romEntry = Entry(romDialogFrame, textvariable=romVar)
def RomSelect(): def RomSelect():
rom = filedialog.askopenfilename() rom = filedialog.askopenfilename()
romVar.set(rom) romVar.set(rom)
romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect) romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect)
baseRomLabel.pack(side=LEFT) baseRomLabel.pack(side=LEFT)
romEntry.pack(side=LEFT) romEntry.pack(side=LEFT)
romSelectButton.pack(side=LEFT) romSelectButton.pack(side=LEFT)
@ -68,7 +69,7 @@ def guiMain(args=None):
baseSpriteLabel.pack(side=LEFT) baseSpriteLabel.pack(side=LEFT)
spriteEntry.pack(side=LEFT) spriteEntry.pack(side=LEFT)
spriteSelectButton.pack(side=LEFT) spriteSelectButton.pack(side=LEFT)
romDialogFrame.pack() romDialogFrame.pack()
spriteDialogFrame.pack() spriteDialogFrame.pack()
@ -84,7 +85,7 @@ def guiMain(args=None):
modeOptionMenu.pack(side=RIGHT) modeOptionMenu.pack(side=RIGHT)
modeLabel = Label(modeFrame, text='Game Mode') modeLabel = Label(modeFrame, text='Game Mode')
modeLabel.pack(side=LEFT) modeLabel.pack(side=LEFT)
logicFrame = Frame(drowDownFrame) logicFrame = Frame(drowDownFrame)
logicVar = StringVar() logicVar = StringVar()
logicVar.set('noglitches') logicVar.set('noglitches')
@ -92,7 +93,7 @@ def guiMain(args=None):
logicOptionMenu.pack(side=RIGHT) logicOptionMenu.pack(side=RIGHT)
logicLabel = Label(logicFrame, text='Game logic') logicLabel = Label(logicFrame, text='Game logic')
logicLabel.pack(side=LEFT) logicLabel.pack(side=LEFT)
goalFrame = Frame(drowDownFrame) goalFrame = Frame(drowDownFrame)
goalVar = StringVar() goalVar = StringVar()
goalVar.set('ganon') goalVar.set('ganon')
@ -100,7 +101,7 @@ def guiMain(args=None):
goalOptionMenu.pack(side=RIGHT) goalOptionMenu.pack(side=RIGHT)
goalLabel = Label(goalFrame, text='Game goal') goalLabel = Label(goalFrame, text='Game goal')
goalLabel.pack(side=LEFT) goalLabel.pack(side=LEFT)
difficultyFrame = Frame(drowDownFrame) difficultyFrame = Frame(drowDownFrame)
difficultyVar = StringVar() difficultyVar = StringVar()
difficultyVar.set('normal') difficultyVar.set('normal')
@ -108,7 +109,7 @@ def guiMain(args=None):
difficultyOptionMenu.pack(side=RIGHT) difficultyOptionMenu.pack(side=RIGHT)
difficultyLabel = Label(difficultyFrame, text='Game difficulty') difficultyLabel = Label(difficultyFrame, text='Game difficulty')
difficultyLabel.pack(side=LEFT) difficultyLabel.pack(side=LEFT)
algorithmFrame = Frame(drowDownFrame) algorithmFrame = Frame(drowDownFrame)
algorithmVar = StringVar() algorithmVar = StringVar()
algorithmVar.set('vt26') algorithmVar.set('vt26')
@ -116,7 +117,7 @@ def guiMain(args=None):
algorithmOptionMenu.pack(side=RIGHT) algorithmOptionMenu.pack(side=RIGHT)
algorithmLabel = Label(algorithmFrame, text='Item distribution algorithm') algorithmLabel = Label(algorithmFrame, text='Item distribution algorithm')
algorithmLabel.pack(side=LEFT) algorithmLabel.pack(side=LEFT)
shuffleFrame = Frame(drowDownFrame) shuffleFrame = Frame(drowDownFrame)
shuffleVar = StringVar() shuffleVar = StringVar()
shuffleVar.set('full') shuffleVar.set('full')
@ -124,7 +125,7 @@ def guiMain(args=None):
shuffleOptionMenu.pack(side=RIGHT) shuffleOptionMenu.pack(side=RIGHT)
shuffleLabel = Label(shuffleFrame, text='Entrance shuffle algorithm') shuffleLabel = Label(shuffleFrame, text='Entrance shuffle algorithm')
shuffleLabel.pack(side=LEFT) shuffleLabel.pack(side=LEFT)
heartbeepFrame = Frame(drowDownFrame) heartbeepFrame = Frame(drowDownFrame)
heartbeepVar = StringVar() heartbeepVar = StringVar()
heartbeepVar.set('normal') heartbeepVar.set('normal')
@ -140,7 +141,7 @@ def guiMain(args=None):
algorithmFrame.pack(expand=True, anchor=E) algorithmFrame.pack(expand=True, anchor=E)
shuffleFrame.pack(expand=True, anchor=E) shuffleFrame.pack(expand=True, anchor=E)
heartbeepFrame.pack(expand=True, anchor=E) heartbeepFrame.pack(expand=True, anchor=E)
bottomFrame = Frame(mainWindow) bottomFrame = Frame(mainWindow)
seedLabel = Label(bottomFrame, text='Seed #') seedLabel = Label(bottomFrame, text='Seed #')

View File

@ -19,7 +19,7 @@ def ItemFactory(items):
else: else:
logging.getLogger('').warning('Unknown Item: %s' % item) logging.getLogger('').warning('Unknown Item: %s' % item)
return None return None
if singleton: if singleton:
return ret[0] return ret[0]
else: else:

View File

@ -40,8 +40,8 @@ def main(args, seed=None):
logger.info('ALttP Entrance Randomizer Version %s - Seed: %s\n\n' % (__version__, world.seed)) logger.info('ALttP Entrance Randomizer Version %s - Seed: %s\n\n' % (__version__, world.seed))
create_regions(world) create_regions(world)
create_dungeons(world); create_dungeons(world)
logger.info('Shuffling the World about.') logger.info('Shuffling the World about.')
@ -91,7 +91,7 @@ def main(args, seed=None):
else: else:
sprite = None sprite = None
outfilebase = 'ER_%s_%s-%s-%s_%s-%s%s%s%s%s_%s' % (world.logic, world.difficulty, world.mode, world.goal, world.shuffle, world.algorithm, "-keysanity" if world.keysanity else "", "-fastmenu" if world.fastmenu else "","-quickswap" if world.quickswap else "", "-shuffleganon" if world.shuffle_ganon else "", world.seed) outfilebase = 'ER_%s_%s-%s-%s_%s-%s%s%s%s%s_%s' % (world.logic, world.difficulty, world.mode, world.goal, world.shuffle, world.algorithm, "-keysanity" if world.keysanity else "", "-fastmenu" if world.fastmenu else "", "-quickswap" if world.quickswap else "", "-shuffleganon" if world.shuffle_ganon else "", world.seed)
if not args.suppress_rom: if not args.suppress_rom:
if args.jsonout: if args.jsonout:
@ -182,7 +182,7 @@ def generate_itempool(world):
world.treasure_hunt_icon = 'Triforce Piece' world.treasure_hunt_icon = 'Triforce Piece'
world.itempool.extend(ItemFactory(['Triforce Piece'] * 30)) world.itempool.extend(ItemFactory(['Triforce Piece'] * 30))
world.itempool.append(ItemFactory('Magic Upgrade (1/2)')) world.itempool.append(ItemFactory('Magic Upgrade (1/2)'))
# shuffle medallions # shuffle medallions
mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
@ -315,4 +315,3 @@ def create_playthrough(world):
# we can finally output our playthrough # we can finally output our playthrough
old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)]) old_world.spoiler.playthrough = OrderedDict([(str(i + 1), {str(location): str(location.item) for location in sphere}) for i, sphere in enumerate(collection_spheres)])

View File

@ -16,10 +16,10 @@ def create_regions(world):
'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Swamp Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']), 'Bonk Fairy (Light)', '50 Rupee Cave', 'Fortune Teller (Light)', 'Lake Hylia Fairy', 'Swamp Fairy', 'Desert Fairy', 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Top of Pyramid']),
create_region('Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']), create_region('Lake Hylia Central Island', None, ['Capacity Upgrade', 'Lake Hylia Central Island Teleporter']),
create_region('Blinds Hideout', ["Blind\'s Hideout - Top", create_region('Blinds Hideout', ["Blind\'s Hideout - Top",
"Blind\'s Hideout - Left", "Blind\'s Hideout - Left",
"Blind\'s Hideout - Right", "Blind\'s Hideout - Right",
"Blind\'s Hideout - Far Left", "Blind\'s Hideout - Far Left",
"Blind\'s Hideout - Far Right"]), "Blind\'s Hideout - Far Right"]),
create_region('Hyrule Castle Secret Entrance', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']), create_region('Hyrule Castle Secret Entrance', ['Link\'s Uncle', 'Secret Passage'], ['Hyrule Castle Secret Entrance Exit']),
create_region('Zoras River', ['King Zora', 'Zora\'s Ledge']), create_region('Zoras River', ['King Zora', 'Zora\'s Ledge']),
create_region('Waterfall of Wishing', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']), create_region('Waterfall of Wishing', ['Waterfall Fairy - Left', 'Waterfall Fairy - Right']),
@ -60,7 +60,7 @@ def create_regions(world):
create_region('Checkerboard Cave', ['Checkerboard Cave']), create_region('Checkerboard Cave', ['Checkerboard Cave']),
create_region('Long Fairy Cave'), create_region('Long Fairy Cave'),
create_region('Mini Moldorm Cave', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', create_region('Mini Moldorm Cave', ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right',
'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']), 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Generous Guy']),
create_region('Ice Rod Cave', ['Ice Rod Cave']), create_region('Ice Rod Cave', ['Ice Rod Cave']),
create_region('Good Bee Cave'), create_region('Good Bee Cave'),
create_region('20 Rupee Cave'), create_region('20 Rupee Cave'),
@ -110,12 +110,12 @@ def create_regions(world):
create_region('Hookshot Fairy'), create_region('Hookshot Fairy'),
create_region('Paradox Cave Front', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)']), create_region('Paradox Cave Front', None, ['Paradox Cave Push Block Reverse', 'Paradox Cave Exit (Bottom)']),
create_region('Paradox Cave Chest Area', ['Paradox Cave Lower - Far Left', create_region('Paradox Cave Chest Area', ['Paradox Cave Lower - Far Left',
'Paradox Cave Lower - Left', 'Paradox Cave Lower - Left',
'Paradox Cave Lower - Right', 'Paradox Cave Lower - Right',
'Paradox Cave Lower - Far Right', 'Paradox Cave Lower - Far Right',
'Paradox Cave Lower - Middle', 'Paradox Cave Lower - Middle',
'Paradox Cave Upper - Left', 'Paradox Cave Upper - Left',
'Paradox Cave Upper - Right'], 'Paradox Cave Upper - Right'],
['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']), ['Paradox Cave Push Block', 'Paradox Cave Bomb Jump']),
create_region('Paradox Cave', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']), create_region('Paradox Cave', None, ['Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Paradox Cave Drop']),
create_region('East Death Mountain (Top)', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge']), create_region('East Death Mountain (Top)', None, ['Paradox Cave (Top)', 'Death Mountain (Top)', 'Spiral Cave Ledge Access', 'East Death Mountain Drop', 'Turtle Rock Teleporter', 'Fairy Ascension Ledge']),
@ -136,7 +136,7 @@ def create_regions(world):
create_region('Palace of Darkness Hint'), create_region('Palace of Darkness Hint'),
create_region('East Dark World Hint'), create_region('East Dark World Hint'),
create_region('South Dark World', ['Stumpy', 'Digging Game', 'Bombos Tablet'], ['Dark Lake Hylia Drop (South)', 'Dark Swamp Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock', create_region('South Dark World', ['Stumpy', 'Digging Game', 'Bombos Tablet'], ['Dark Lake Hylia Drop (South)', 'Dark Swamp Cave', 'Swamp Palace', 'Village of Outcasts Heavy Rock',
'Maze Race Mirror Spot', 'Cave 45', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop']), 'Maze Race Mirror Spot', 'Cave 45', 'East Dark World Bridge', 'Big Bomb Shop', 'Archery Game', 'Bonk Fairy (Dark)', 'Dark Lake Hylia Shop']),
create_region('Big Bomb Shop'), create_region('Big Bomb Shop'),
create_region('Archery Game'), create_region('Archery Game'),
create_region('Dark Lake Hylia', None, ['Lake Hylia Island Mirror Spot', 'East Dark World Pier', 'Dark Lake Hylia Ledge']), create_region('Dark Lake Hylia', None, ['Lake Hylia Island Mirror Spot', 'East Dark World Pier', 'Dark Lake Hylia Ledge']),
@ -261,8 +261,8 @@ def create_regions(world):
create_region('Pyramid', ['Ganon'], ['Ganon Drop']), create_region('Pyramid', ['Ganon'], ['Ganon Drop']),
create_region('Bottom of Pyramid', None, ['Pyramid Exit']), create_region('Bottom of Pyramid', None, ['Pyramid Exit']),
create_region('Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']) create_region('Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop'])
] ]
world.intialize_regions() world.intialize_regions()

62
Rom.py
View File

@ -64,7 +64,7 @@ class LocalRom(object):
patchedmd5 = hashlib.md5() patchedmd5 = hashlib.md5()
patchedmd5.update(self.buffer) patchedmd5.update(self.buffer)
if not RANDOMIZERBASEHASH == patchedmd5.hexdigest(): if not RANDOMIZERBASEHASH == patchedmd5.hexdigest():
raise RuntimeError('Provided Base Rom unsuitable for patching. Please provide a JAP(1.0) "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc" rom to use as a base.') raise RuntimeError('Provided Base Rom unsuitable for patching. Please provide a JAP(1.0) "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc" rom to use as a base.')
def write_crc(self): def write_crc(self):
# this does not seem to work # this does not seem to work
@ -83,12 +83,14 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
locationaddress = location.address locationaddress = location.address
if not location.crystal: if not location.crystal:
#Keys in their native dungeon should use the orignal item code for keys # Keys in their native dungeon should use the orignal item code for keys
if location.parent_region.dungeon: if location.parent_region.dungeon:
dungeon=location.parent_region.dungeon dungeon = location.parent_region.dungeon
if location.item.key and dungeon.is_dungeon_item(location.item): if location.item.key and dungeon.is_dungeon_item(location.item):
if location.item.type == "BigKey": itemid = 0x32 if location.item.type == "BigKey":
if location.item.type == "SmallKey": itemid = 0x24 itemid = 0x32
if location.item.type == "SmallKey":
itemid = 0x24
rom.write_byte(locationaddress, itemid) rom.write_byte(locationaddress, itemid)
else: else:
# crystals # crystals
@ -103,9 +105,9 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
music = 0x11 if 'Pendant' in location.item.name else 0x16 music = 0x11 if 'Pendant' in location.item.name else 0x16
for music_address in music_addresses: for music_address in music_addresses:
rom.write_byte(music_address, music) rom.write_byte(music_address, music)
if world.keysanity: if world.keysanity:
rom.write_byte(0x155C9, random.choice([0x11, 0x16])) #Randomize GT music too in keysanity mode rom.write_byte(0x155C9, random.choice([0x11, 0x16])) # Randomize GT music too in keysanity mode
# patch entrances # patch entrances
for region in world.regions: for region in world.regions:
@ -316,15 +318,15 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
rom.write_byte(0x18016A, 0x01 if world.keysanity else 0x00) # free roaming item text boxes rom.write_byte(0x18016A, 0x01 if world.keysanity else 0x00) # free roaming item text boxes
rom.write_byte(0x18003B, 0x01 if world.keysanity else 0x00) # maps showing crystals on overworld rom.write_byte(0x18003B, 0x01 if world.keysanity else 0x00) # maps showing crystals on overworld
# compasses showing dungeon count # compasses showing dungeon count
if world.clock_mode != 'off': if world.clock_mode != 'off':
rom.write_byte(0x18003C, 0x00) #Currently must be off if timer is on, because they use same HUD location rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location
elif world.keysanity: elif world.keysanity:
rom.write_byte(0x18003C, 0x01) #show on pickup rom.write_byte(0x18003C, 0x01) # show on pickup
else: else:
rom.write_byte(0x18003C, 0x00) rom.write_byte(0x18003C, 0x00)
rom.write_byte(0x180045, 0x01 if world.keysanity else 0x00) # free roaming items in menu rom.write_byte(0x180045, 0x01 if world.keysanity else 0x00) # free roaming items in menu
digging_game_rng = random.randint(1, 30) # set rng for digging game digging_game_rng = random.randint(1, 30) # set rng for digging game
rom.write_byte(0x180020, digging_game_rng) rom.write_byte(0x180020, digging_game_rng)
@ -375,29 +377,29 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
rom.write_byte(0x15E25, 0xA4) rom.write_byte(0x15E25, 0xA4)
# todo fix screen scrolling # todo fix screen scrolling
#enable instant item menu # enable instant item menu
if world.fastmenu: if world.fastmenu:
rom.write_byte(0x180048, 0x01) rom.write_byte(0x180048, 0x01)
# Sound twekas for fastmenu: # Sound twekas for fastmenu:
rom.write_byte(0x6DD9A, 0x20) rom.write_byte(0x6DD9A, 0x20)
rom.write_byte(0x6DF2A, 0x20) rom.write_byte(0x6DF2A, 0x20)
rom.write_byte(0x6E0E9, 0x20) rom.write_byte(0x6E0E9, 0x20)
# enable quick item swapping with L and R (ported by Amazing Ampharos) # enable quick item swapping with L and R (ported by Amazing Ampharos)
if world.quickswap: if world.quickswap:
rom.write_bytes(0x107fb, [0x22, 0x50, 0xFF, 0x1F]) rom.write_bytes(0x107fb, [0x22, 0x50, 0xFF, 0x1F])
rom.write_bytes(0x12451, [0x22, 0x50, 0xFF, 0x1F]) rom.write_bytes(0x12451, [0x22, 0x50, 0xFF, 0x1F])
rom.write_bytes(0xfff50, [0x20, 0x58, 0xFF, 0xA5, 0xF6, 0x29, 0x40, 0x6B, 0xA5, 0xF6, 0x89, 0x10, 0xF0, 0x03, 0x4C, 0x69, rom.write_bytes(0xfff50, [0x20, 0x58, 0xFF, 0xA5, 0xF6, 0x29, 0x40, 0x6B, 0xA5, 0xF6, 0x89, 0x10, 0xF0, 0x03, 0x4C, 0x69,
0xFF, 0x89, 0x20, 0xF0, 0x03, 0x4C, 0xAA, 0xFF, 0x60, 0xAD, 0x02, 0x02, 0xF0, 0x3B, 0xDA, 0xAA, 0xFF, 0x89, 0x20, 0xF0, 0x03, 0x4C, 0xAA, 0xFF, 0x60, 0xAD, 0x02, 0x02, 0xF0, 0x3B, 0xDA, 0xAA,
0xE0, 0x0F, 0xF0, 0x14, 0xE0, 0x10, 0xF0, 0x14, 0xE0, 0x14, 0xD0, 0x02, 0xA2, 0x00, 0xE8, 0xBF, 0xE0, 0x0F, 0xF0, 0x14, 0xE0, 0x10, 0xF0, 0x14, 0xE0, 0x14, 0xD0, 0x02, 0xA2, 0x00, 0xE8, 0xBF,
0x3F, 0xF3, 0x7E, 0xF0, 0xEB, 0x4C, 0xEB, 0xFF, 0xA2, 0x01, 0x80, 0x0A, 0xAF, 0x4F, 0xF3, 0x7E, 0x3F, 0xF3, 0x7E, 0xF0, 0xEB, 0x4C, 0xEB, 0xFF, 0xA2, 0x01, 0x80, 0x0A, 0xAF, 0x4F, 0xF3, 0x7E,
0xAA, 0xE0, 0x04, 0xF0, 0x10, 0xE8, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F, 0xF3, 0xAA, 0xE0, 0x04, 0xF0, 0x10, 0xE8, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F, 0xF3,
0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x11, 0x80, 0xD6, 0x60, 0xAD, 0x02, 0x02, 0xF0, 0x3B, 0xDA, 0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x11, 0x80, 0xD6, 0x60, 0xAD, 0x02, 0x02, 0xF0, 0x3B, 0xDA,
0xAA, 0xE0, 0x11, 0xF0, 0x14, 0xE0, 0x10, 0xF0, 0x14, 0xE0, 0x01, 0xD0, 0x02, 0xA2, 0x15, 0xCA, 0xAA, 0xE0, 0x11, 0xF0, 0x14, 0xE0, 0x10, 0xF0, 0x14, 0xE0, 0x01, 0xD0, 0x02, 0xA2, 0x15, 0xCA,
0xBF, 0x3F, 0xF3, 0x7E, 0xF0, 0xEB, 0x4C, 0xEB, 0xFF, 0xA2, 0x04, 0x80, 0x0A, 0xAF, 0x4F, 0xF3, 0xBF, 0x3F, 0xF3, 0x7E, 0xF0, 0xEB, 0x4C, 0xEB, 0xFF, 0xA2, 0x04, 0x80, 0x0A, 0xAF, 0x4F, 0xF3,
0x7E, 0xAA, 0xE0, 0x01, 0xF0, 0x10, 0xCA, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F, 0x7E, 0xAA, 0xE0, 0x01, 0xF0, 0x10, 0xCA, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F,
0xF3, 0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x0F, 0x80, 0xD6, 0x60, 0xA9, 0x20, 0x8D, 0x2F, 0x01, 0xF3, 0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x0F, 0x80, 0xD6, 0x60, 0xA9, 0x20, 0x8D, 0x2F, 0x01,
0x8E, 0x02, 0x02, 0x22, 0x7F, 0xDB, 0x0D, 0xFA, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) 0x8E, 0x02, 0x02, 0x22, 0x7F, 0xDB, 0x0D, 0xFA, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
write_strings(rom, world) write_strings(rom, world)
@ -502,16 +504,16 @@ def write_strings(rom, world):
sickkiditem = world.get_location('Sick Kid').item sickkiditem = world.get_location('Sick Kid').item
sickkiditem_text = SickKid_texts[random.randint(0, len(SickKid_texts) - 1)] if sickkiditem is None or sickkiditem.sickkid_credit_text is None else sickkiditem.sickkid_credit_text sickkiditem_text = SickKid_texts[random.randint(0, len(SickKid_texts) - 1)] if sickkiditem is None or sickkiditem.sickkid_credit_text is None else sickkiditem.sickkid_credit_text
write_credits_string_to_rom(rom, 'SickKid', sickkiditem_text) write_credits_string_to_rom(rom, 'SickKid', sickkiditem_text)
zoraitem = world.get_location('King Zora').item zoraitem = world.get_location('King Zora').item
zoraitem_text = Zora_texts[random.randint(0, len(Zora_texts) - 1)] if zoraitem is None or zoraitem.zora_credit_text is None else zoraitem.zora_credit_text zoraitem_text = Zora_texts[random.randint(0, len(Zora_texts) - 1)] if zoraitem is None or zoraitem.zora_credit_text is None else zoraitem.zora_credit_text
write_credits_string_to_rom(rom, 'Zora', zoraitem_text) write_credits_string_to_rom(rom, 'Zora', zoraitem_text)
magicshopitem = world.get_location('Potion Shop').item magicshopitem = world.get_location('Potion Shop').item
magicshopitem_text = MagicShop_texts[random.randint(0, len(MagicShop_texts) - 1)] if magicshopitem is None or magicshopitem.magicshop_credit_text is None else magicshopitem.magicshop_credit_text magicshopitem_text = MagicShop_texts[random.randint(0, len(MagicShop_texts) - 1)] if magicshopitem is None or magicshopitem.magicshop_credit_text is None else magicshopitem.magicshop_credit_text
write_credits_string_to_rom(rom, 'MagicShop', magicshopitem_text) write_credits_string_to_rom(rom, 'MagicShop', magicshopitem_text)
fluteboyitem = world.get_location('Stumpy').item fluteboyitem = world.get_location('Stumpy').item
fluteboyitem_text = FluteBoy_texts[random.randint(0, len(FluteBoy_texts) - 1)] if fluteboyitem is None or fluteboyitem.fluteboy_credit_text is None else fluteboyitem.fluteboy_credit_text fluteboyitem_text = FluteBoy_texts[random.randint(0, len(FluteBoy_texts) - 1)] if fluteboyitem is None or fluteboyitem.fluteboy_credit_text is None else fluteboyitem.fluteboy_credit_text
write_credits_string_to_rom(rom, 'FluteBoy', fluteboyitem_text) write_credits_string_to_rom(rom, 'FluteBoy', fluteboyitem_text)

View File

@ -3,7 +3,7 @@ import logging
def set_rules(world): def set_rules(world):
global_rules(world) global_rules(world)
if world.mode == 'open': if world.mode == 'open':
open_rules(world) open_rules(world)
elif world.mode == 'standard': elif world.mode == 'standard':
@ -20,8 +20,6 @@ def set_rules(world):
else: else:
raise NotImplementedError('Not implemented yet') raise NotImplementedError('Not implemented yet')
if world.goal == 'dungeons': if world.goal == 'dungeons':
# require all dungeons to beat ganon # require all dungeons to beat ganon
add_rule(world.get_location('Ganon'), lambda state: state.can_reach('Master Sword Pedestal', 'Location') and state.has('Beat Agahnim 1') and state.has('Beat Agahnim 2')) add_rule(world.get_location('Ganon'), lambda state: state.can_reach('Master Sword Pedestal', 'Location') and state.has('Beat Agahnim 1') and state.has('Beat Agahnim 2'))
@ -55,10 +53,11 @@ def add_lamp_requirement(spot):
def forbid_item(location, item): def forbid_item(location, item):
old_rule = location.item_rule old_rule = location.item_rule
location.item_rule = lambda i: i.name != item and old_rule(i) location.item_rule = lambda i: i.name != item and old_rule(i)
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 loc.item is not None and loc.item.name == item:
return True return True
return False return False
@ -205,10 +204,9 @@ def global_rules(world):
(state.has_blunt_weapon() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Bow'))) (state.has_blunt_weapon() or state.has('Fire Rod') or state.has('Ice Rod') or state.has('Bow')))
for location in ['Desert Palace - Lanmolas', 'Desert Palace - Big Chest']: for location in ['Desert Palace - Lanmolas', 'Desert Palace - Big Chest']:
forbid_item(world.get_location(location), 'Big Key (Desert Palace)') forbid_item(world.get_location(location), 'Big Key (Desert Palace)')
for location in ['Desert Palace - Lanmolas', 'Desert Palace - Big Key Chest', 'Desert Palace - Compass Chest']: for location in ['Desert Palace - Lanmolas', 'Desert Palace - Big Key Chest', 'Desert Palace - Compass Chest']:
forbid_item(world.get_location(location), 'Small Key (Desert Palace)') forbid_item(world.get_location(location), 'Small Key (Desert Palace)')
set_rule(world.get_entrance('Tower of Hera Small Key Door'), lambda state: state.has('Small Key (Tower of Hera)')) set_rule(world.get_entrance('Tower of Hera Small Key Door'), lambda state: state.has('Small Key (Tower of Hera)'))
set_rule(world.get_entrance('Tower of Hera Big Key Door'), lambda state: state.has('Big Key (Tower of Hera)')) set_rule(world.get_entrance('Tower of Hera Big Key Door'), lambda state: state.has('Big Key (Tower of Hera)'))
@ -242,7 +240,7 @@ def global_rules(world):
set_rule(world.get_entrance('Skull Woods First Section South Door'), lambda state: state.has('Small Key (Skull Woods)')) set_rule(world.get_entrance('Skull Woods First Section South Door'), lambda state: state.has('Small Key (Skull Woods)'))
set_rule(world.get_entrance('Skull Woods First Section (Right) North Door'), lambda state: state.has('Small Key (Skull Woods)')) set_rule(world.get_entrance('Skull Woods First Section (Right) North Door'), lambda state: state.has('Small Key (Skull Woods)'))
set_rule(world.get_entrance('Skull Woods First Section West Door'), lambda state: state.has('Small Key (Skull Woods)', 2)) #ideally would only be one key, but we may have spent thst key already on escaping the right section set_rule(world.get_entrance('Skull Woods First Section West Door'), lambda state: state.has('Small Key (Skull Woods)', 2)) # ideally would only be one key, but we may have spent thst key already on escaping the right section
set_rule(world.get_entrance('Skull Woods First Section (Left) Door to Exit'), lambda state: state.has('Small Key (Skull Woods)', 2)) set_rule(world.get_entrance('Skull Woods First Section (Left) Door to Exit'), lambda state: state.has('Small Key (Skull Woods)', 2))
set_rule(world.get_location('Skull Woods - Big Chest'), lambda state: state.has('Big Key (Skull Woods)')) set_rule(world.get_location('Skull Woods - Big Chest'), lambda state: state.has('Big Key (Skull Woods)'))
set_rule(world.get_entrance('Skull Woods Torch Room'), lambda state: state.has('Small Key (Skull Woods)', 3) and state.has('Fire Rod') and state.has_sword()) # sword required for curtain set_rule(world.get_entrance('Skull Woods Torch Room'), lambda state: state.has('Small Key (Skull Woods)', 3) and state.has('Fire Rod') and state.has_sword()) # sword required for curtain
@ -254,7 +252,7 @@ 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 (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)')
@ -270,7 +268,7 @@ def global_rules(world):
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 ((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
(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)) (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))
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()))
@ -293,7 +291,7 @@ def global_rules(world):
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.has('Bottle') or state.has('Half Magic') or state.has('Quarter Magic')))
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'))
@ -307,7 +305,7 @@ def global_rules(world):
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)'))
for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Helmasaur']: for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Helmasaur']:
forbid_item(world.get_location(location), 'Big Key (Palace of Darkness)') forbid_item(world.get_location(location), 'Big Key (Palace of Darkness)')
for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom']: for location in ['Palace of Darkness - Big Chest', 'Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom']:
forbid_item(world.get_location(location), 'Small Key (Palace of Darkness)') forbid_item(world.get_location(location), 'Small Key (Palace of Darkness)')
@ -351,7 +349,7 @@ def no_glitches_rules(world):
add_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hookshot')) add_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hookshot'))
set_rule(world.get_entrance('Paradox Cave Push Block Reverse'), lambda state: False) # no glitches does not require block override set_rule(world.get_entrance('Paradox Cave Push Block Reverse'), lambda state: False) # no glitches does not require block override
set_rule(world.get_entrance('Paradox Cave Bomb Jump'), lambda state: False) set_rule(world.get_entrance('Paradox Cave Bomb Jump'), lambda state: False)
set_rule(world.get_entrance('Skull Woods First Section Bomb Jump'), lambda state: False) set_rule(world.get_entrance('Skull Woods First Section Bomb Jump'), lambda state: False)
# Light cones in standard depend on which world we actually are in, not which one the location would normally be # 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 # We add Lamp requirements only to those locations which lie in the dark world (or everything if open
@ -462,7 +460,7 @@ def set_trock_key_rules(world):
for location in non_big_key_locations: for location in non_big_key_locations:
forbid_item(world.get_location(location), 'Big Key (Turtle Rock)') forbid_item(world.get_location(location), 'Big Key (Turtle Rock)')
# small key restriction # small key restriction
for location in ['Turtle Rock - Trinexx']: for location in ['Turtle Rock - Trinexx']:
forbid_item(world.get_location(location), 'Small Key (Turtle Rock)') forbid_item(world.get_location(location), 'Small Key (Turtle Rock)')
@ -531,8 +529,8 @@ def set_big_bomb_rules(world):
'Cave Shop (Dark Death Mountain)', 'Cave Shop (Dark Death Mountain)',
'Dark Death Mountain Fairy', 'Dark Death Mountain Fairy',
'Mimic Cave Mirror Spot'] 'Mimic Cave Mirror Spot']
Isolated_LW_entrances =['Capacity Upgrade', Isolated_LW_entrances = ['Capacity Upgrade',
'Hookshot Fairy'] 'Hookshot Fairy']
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Pearl() and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6')) set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Pearl() and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6'))
if bombshop_entrance.name in Normal_LW_entrances: if bombshop_entrance.name in Normal_LW_entrances:
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()) or state.has_Mirror()) add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()) or state.has_Mirror())