Merge branch 'main' of https://github.com/Berserker66/MultiWorld-Utilities into triforce_changes
This commit is contained in:
commit
222784dbb6
129
Adjuster.py
129
Adjuster.py
|
@ -4,9 +4,11 @@ import os
|
||||||
import logging
|
import logging
|
||||||
import textwrap
|
import textwrap
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from Rom import Sprite, LocalRom, apply_rom_settings
|
||||||
|
from Utils import output_path
|
||||||
|
|
||||||
from AdjusterMain import adjust
|
|
||||||
from Rom import Sprite
|
|
||||||
|
|
||||||
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
|
class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
|
||||||
|
|
||||||
|
@ -34,6 +36,7 @@ def main():
|
||||||
(Both can be revealed when speaking to Murahalda)
|
(Both can be revealed when speaking to Murahalda)
|
||||||
(default: %(default)s)
|
(default: %(default)s)
|
||||||
''')
|
''')
|
||||||
|
parser.add_argument('--enableflashing', help='Reenable flashing animations (unfriendly to epilepsy, always disabled in race roms)', action='store_false', dest="reduceflashing")
|
||||||
parser.add_argument('--heartbeep', default='normal', const='normal', nargs='?', choices=['double', 'normal', 'half', 'quarter', 'off'],
|
parser.add_argument('--heartbeep', default='normal', const='normal', nargs='?', choices=['double', 'normal', 'half', 'quarter', 'off'],
|
||||||
help='''\
|
help='''\
|
||||||
Select the rate at which the heart beep sound is played at
|
Select the rate at which the heart beep sound is played at
|
||||||
|
@ -57,25 +60,127 @@ def main():
|
||||||
parser.add_argument('--names', default='', type=str)
|
parser.add_argument('--names', default='', type=str)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# ToDo: Validate files further than mere existance
|
|
||||||
if not os.path.isfile(args.rom):
|
|
||||||
input(
|
|
||||||
'Could not find valid rom for patching at expected path %s. Please run with -h to see help for further information. \nPress Enter to exit.' % args.rom)
|
|
||||||
sys.exit(1)
|
|
||||||
if args.sprite is not None and not os.path.isfile(args.sprite) and not Sprite.get_sprite_from_name(args.sprite):
|
|
||||||
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# set up logger
|
# set up logger
|
||||||
loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[
|
loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[
|
||||||
args.loglevel]
|
args.loglevel]
|
||||||
logging.basicConfig(format='%(message)s', level=loglevel)
|
logging.basicConfig(format='%(message)s', level=loglevel)
|
||||||
|
|
||||||
|
if not os.path.isfile(args.rom):
|
||||||
|
adjustGUI()
|
||||||
|
else:
|
||||||
|
if args.sprite is not None and not os.path.isfile(args.sprite) and not Sprite.get_sprite_from_name(args.sprite):
|
||||||
|
input('Could not find link sprite sheet at given location. \nPress Enter to exit.')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
args, path = adjust(args=args)
|
args, path = adjust(args=args)
|
||||||
from Utils import persistent_store
|
from Utils import persistent_store
|
||||||
from Rom import Sprite
|
|
||||||
if isinstance(args.sprite, Sprite):
|
if isinstance(args.sprite, Sprite):
|
||||||
args.sprite = args.sprite.name
|
args.sprite = args.sprite.name
|
||||||
persistent_store("adjuster", "last_settings_3", args)
|
persistent_store("adjuster", "last_settings_3", args)
|
||||||
|
|
||||||
|
|
||||||
|
def adjust(args):
|
||||||
|
start = time.perf_counter()
|
||||||
|
logger = logging.getLogger('Adjuster')
|
||||||
|
logger.info('Patching ROM.')
|
||||||
|
vanillaRom = args.baserom
|
||||||
|
if os.path.splitext(args.rom)[-1].lower() == '.bmbp':
|
||||||
|
import Patch
|
||||||
|
meta, args.rom = Patch.create_rom_file(args.rom)
|
||||||
|
|
||||||
|
if os.stat(args.rom).st_size in (0x200000, 0x400000) and os.path.splitext(args.rom)[-1].lower() == '.sfc':
|
||||||
|
rom = LocalRom(args.rom, patch=False, vanillaRom=vanillaRom)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(
|
||||||
|
'Provided Rom is not a valid Link to the Past Randomizer Rom. Please provide one for adjusting.')
|
||||||
|
palettes_options={}
|
||||||
|
palettes_options['dungeon']=args.uw_palettes
|
||||||
|
|
||||||
|
palettes_options['overworld']=args.ow_palettes
|
||||||
|
palettes_options['hud']=args.hud_palettes
|
||||||
|
palettes_options['sword']=args.sword_palettes
|
||||||
|
palettes_options['shield']=args.shield_palettes
|
||||||
|
# palettes_options['link']=args.link_palettesvera
|
||||||
|
racerom = rom.read_byte(0x180213) > 0
|
||||||
|
|
||||||
|
apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic,
|
||||||
|
args.sprite, palettes_options, reduceflashing=args.reduceflashing or racerom)
|
||||||
|
path = output_path(f'{os.path.basename(args.rom)[:-4]}_adjusted.sfc')
|
||||||
|
rom.write_to_file(path)
|
||||||
|
|
||||||
|
logger.info('Done. Enjoy.')
|
||||||
|
logger.debug('Total Time: %s', time.perf_counter() - start)
|
||||||
|
|
||||||
|
return args, path
|
||||||
|
|
||||||
|
def adjustGUI():
|
||||||
|
from tkinter import Checkbutton, OptionMenu, Toplevel, LabelFrame, PhotoImage, Tk, LEFT, RIGHT, BOTTOM, TOP, \
|
||||||
|
StringVar, IntVar, Frame, Label, W, E, X, BOTH, Entry, Spinbox, Button, filedialog, messagebox, ttk
|
||||||
|
from Gui import get_rom_options_frame, get_rom_frame
|
||||||
|
from GuiUtils import set_icon
|
||||||
|
from argparse import Namespace
|
||||||
|
from Main import __version__ as MWVersion
|
||||||
|
adjustWindow = Tk()
|
||||||
|
adjustWindow.wm_title("Berserker's Multiworld %s LttP Adjuster" % MWVersion)
|
||||||
|
set_icon(adjustWindow)
|
||||||
|
|
||||||
|
rom_options_frame, rom_vars, set_sprite = get_rom_options_frame(adjustWindow)
|
||||||
|
|
||||||
|
bottomFrame2 = Frame(adjustWindow)
|
||||||
|
|
||||||
|
romFrame, romVar = get_rom_frame(adjustWindow)
|
||||||
|
|
||||||
|
romDialogFrame = Frame(adjustWindow)
|
||||||
|
baseRomLabel2 = Label(romDialogFrame, text='Rom to adjust')
|
||||||
|
romVar2 = StringVar()
|
||||||
|
romEntry2 = Entry(romDialogFrame, textvariable=romVar2)
|
||||||
|
|
||||||
|
def RomSelect2():
|
||||||
|
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc", ".bmbp")), ("All Files", "*")])
|
||||||
|
romVar2.set(rom)
|
||||||
|
romSelectButton2 = Button(romDialogFrame, text='Select Rom', command=RomSelect2)
|
||||||
|
romDialogFrame.pack(side=TOP, expand=True, fill=X)
|
||||||
|
baseRomLabel2.pack(side=LEFT)
|
||||||
|
romEntry2.pack(side=LEFT, expand=True, fill=X)
|
||||||
|
romSelectButton2.pack(side=LEFT)
|
||||||
|
|
||||||
|
def adjustRom():
|
||||||
|
guiargs = Namespace()
|
||||||
|
guiargs.heartbeep = rom_vars.heartbeepVar.get()
|
||||||
|
guiargs.heartcolor = rom_vars.heartcolorVar.get()
|
||||||
|
guiargs.fastmenu = rom_vars.fastMenuVar.get()
|
||||||
|
guiargs.ow_palettes = rom_vars.owPalettesVar.get()
|
||||||
|
guiargs.uw_palettes = rom_vars.uwPalettesVar.get()
|
||||||
|
guiargs.hud_palettes = rom_vars.hudPalettesVar.get()
|
||||||
|
guiargs.sword_palettes = rom_vars.swordPalettesVar.get()
|
||||||
|
guiargs.shield_palettes = rom_vars.shieldPalettesVar.get()
|
||||||
|
guiargs.quickswap = bool(rom_vars.quickSwapVar.get())
|
||||||
|
guiargs.disablemusic = bool(rom_vars.disableMusicVar.get())
|
||||||
|
guiargs.reduceflashing = bool(rom_vars.disableFlashingVar.get())
|
||||||
|
guiargs.rom = romVar2.get()
|
||||||
|
guiargs.baserom = romVar.get()
|
||||||
|
guiargs.sprite = rom_vars.sprite
|
||||||
|
try:
|
||||||
|
guiargs, path = adjust(args=guiargs)
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(e)
|
||||||
|
messagebox.showerror(title="Error while adjusting Rom", message=str(e))
|
||||||
|
else:
|
||||||
|
messagebox.showinfo(title="Success", message=f"Rom patched successfully to {path}")
|
||||||
|
from Utils import persistent_store
|
||||||
|
from Rom import Sprite
|
||||||
|
if isinstance(guiargs.sprite, Sprite):
|
||||||
|
guiargs.sprite = guiargs.sprite.name
|
||||||
|
persistent_store("adjuster", "last_settings_3", guiargs)
|
||||||
|
|
||||||
|
adjustButton = Button(bottomFrame2, text='Adjust Rom', command=adjustRom)
|
||||||
|
rom_options_frame.pack(side=TOP)
|
||||||
|
adjustButton.pack(side=BOTTOM, padx=(5, 5))
|
||||||
|
|
||||||
|
bottomFrame2.pack(side=BOTTOM, pady=(5, 5))
|
||||||
|
|
||||||
|
adjustWindow.mainloop()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
|
@ -4,6 +4,7 @@ import copy
|
||||||
from enum import Enum, unique
|
from enum import Enum, unique
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
import functools
|
||||||
from collections import OrderedDict, Counter, deque
|
from collections import OrderedDict, Counter, deque
|
||||||
from typing import Union, Optional, List, Dict, NamedTuple, Iterable
|
from typing import Union, Optional, List, Dict, NamedTuple, Iterable
|
||||||
import secrets
|
import secrets
|
||||||
|
@ -24,8 +25,9 @@ class World(object):
|
||||||
plando_texts: List[Dict[str, str]]
|
plando_texts: List[Dict[str, str]]
|
||||||
plando_items: List[PlandoItem]
|
plando_items: List[PlandoItem]
|
||||||
plando_connections: List[PlandoConnection]
|
plando_connections: List[PlandoConnection]
|
||||||
|
er_seeds: Dict[int, str]
|
||||||
|
|
||||||
def __init__(self, players: int, shuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer,
|
def __init__(self, players: int, shuffle, logic, mode, swords, difficulty, item_functionality, timer,
|
||||||
progressive,
|
progressive,
|
||||||
goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints):
|
goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints):
|
||||||
if self.debug_types:
|
if self.debug_types:
|
||||||
|
@ -46,7 +48,7 @@ class World(object):
|
||||||
self.mode = mode.copy()
|
self.mode = mode.copy()
|
||||||
self.swords = swords.copy()
|
self.swords = swords.copy()
|
||||||
self.difficulty = difficulty.copy()
|
self.difficulty = difficulty.copy()
|
||||||
self.difficulty_adjustments = difficulty_adjustments.copy()
|
self.item_functionality = item_functionality.copy()
|
||||||
self.timer = timer.copy()
|
self.timer = timer.copy()
|
||||||
self.progressive = progressive
|
self.progressive = progressive
|
||||||
self.goal = goal.copy()
|
self.goal = goal.copy()
|
||||||
|
@ -160,6 +162,10 @@ class World(object):
|
||||||
region.world = self
|
region.world = self
|
||||||
self._region_cache[region.player][region.name] = region
|
self._region_cache[region.player][region.name] = region
|
||||||
|
|
||||||
|
@functools.cached_property
|
||||||
|
def world_name_lookup(self):
|
||||||
|
return {self.player_names[player_id][0]: player_id for player_id in self.player_ids}
|
||||||
|
|
||||||
def _recache(self):
|
def _recache(self):
|
||||||
"""Rebuild world cache"""
|
"""Rebuild world cache"""
|
||||||
for region in self.regions:
|
for region in self.regions:
|
||||||
|
@ -450,7 +456,7 @@ class World(object):
|
||||||
def get_spheres(self):
|
def get_spheres(self):
|
||||||
state = CollectionState(self)
|
state = CollectionState(self)
|
||||||
|
|
||||||
locations = {location for location in self.get_locations()}
|
locations = set(self.get_locations())
|
||||||
|
|
||||||
while locations:
|
while locations:
|
||||||
sphere = set()
|
sphere = set()
|
||||||
|
@ -458,7 +464,10 @@ class World(object):
|
||||||
for location in locations:
|
for location in locations:
|
||||||
if location.can_reach(state):
|
if location.can_reach(state):
|
||||||
sphere.add(location)
|
sphere.add(location)
|
||||||
yield sphere
|
sphere_list = list(sphere)
|
||||||
|
sphere_list.sort(key=lambda location: location.name)
|
||||||
|
self.random.shuffle(sphere_list)
|
||||||
|
yield sphere_list
|
||||||
if not sphere:
|
if not sphere:
|
||||||
if locations:
|
if locations:
|
||||||
yield locations # unreachable locations
|
yield locations # unreachable locations
|
||||||
|
@ -601,11 +610,13 @@ class CollectionState(object):
|
||||||
if locations is None:
|
if locations is None:
|
||||||
locations = self.world.get_filled_locations()
|
locations = self.world.get_filled_locations()
|
||||||
new_locations = True
|
new_locations = True
|
||||||
|
# since the loop has a good chance to run more than once, only filter the events once
|
||||||
|
locations = {location for location in locations if location.event}
|
||||||
while new_locations:
|
while new_locations:
|
||||||
reachable_events = {location for location in locations if location.event and
|
reachable_events = {location for location in locations if
|
||||||
(not key_only or (not self.world.keyshuffle[
|
(not key_only or
|
||||||
location.item.player] and location.item.smallkey) or (not self.world.bigkeyshuffle[
|
(not self.world.keyshuffle[location.item.player] and location.item.smallkey)
|
||||||
location.item.player] and location.item.bigkey))
|
or (not self.world.bigkeyshuffle[location.item.player] and location.item.bigkey))
|
||||||
and location.can_reach(self)}
|
and location.can_reach(self)}
|
||||||
new_locations = reachable_events - self.events
|
new_locations = reachable_events - self.events
|
||||||
for event in new_locations:
|
for event in new_locations:
|
||||||
|
@ -688,9 +699,9 @@ class CollectionState(object):
|
||||||
elif self.has('Magic Upgrade (1/2)', player):
|
elif self.has('Magic Upgrade (1/2)', player):
|
||||||
basemagic = 16
|
basemagic = 16
|
||||||
if self.can_buy_unlimited('Green Potion', player) or self.can_buy_unlimited('Blue Potion', player):
|
if self.can_buy_unlimited('Green Potion', player) or self.can_buy_unlimited('Blue Potion', player):
|
||||||
if self.world.difficulty_adjustments[player] == 'hard' and not fullrefill:
|
if self.world.item_functionality[player] == 'hard' and not fullrefill:
|
||||||
basemagic = basemagic + int(basemagic * 0.5 * self.bottle_count(player))
|
basemagic = basemagic + int(basemagic * 0.5 * self.bottle_count(player))
|
||||||
elif self.world.difficulty_adjustments[player] == 'expert' and not fullrefill:
|
elif self.world.item_functionality[player] == 'expert' and not fullrefill:
|
||||||
basemagic = basemagic + int(basemagic * 0.25 * self.bottle_count(player))
|
basemagic = basemagic + int(basemagic * 0.25 * self.bottle_count(player))
|
||||||
else:
|
else:
|
||||||
basemagic = basemagic + basemagic * self.bottle_count(player)
|
basemagic = basemagic + basemagic * self.bottle_count(player)
|
||||||
|
@ -748,10 +759,6 @@ class CollectionState(object):
|
||||||
def has_fire_source(self, player: int) -> bool:
|
def has_fire_source(self, player: int) -> bool:
|
||||||
return self.has('Fire Rod', player) or self.has('Lamp', player)
|
return self.has('Fire Rod', player) or self.has('Lamp', player)
|
||||||
|
|
||||||
def can_flute(self, player: int) -> bool:
|
|
||||||
lw = self.world.get_region('Light World', player)
|
|
||||||
return self.has('Flute', player) and lw.can_reach(self) and self.is_not_bunny(lw, player)
|
|
||||||
|
|
||||||
def can_melt_things(self, player: int) -> bool:
|
def can_melt_things(self, player: int) -> bool:
|
||||||
return self.has('Fire Rod', player) or \
|
return self.has('Fire Rod', player) or \
|
||||||
(self.has('Bombos', player) and
|
(self.has('Bombos', player) and
|
||||||
|
@ -808,7 +815,7 @@ class CollectionState(object):
|
||||||
rules.append(self.has_Pearl(player))
|
rules.append(self.has_Pearl(player))
|
||||||
return all(rules)
|
return all(rules)
|
||||||
|
|
||||||
def collect(self, item: Item, event=False, location=None):
|
def collect(self, item: Item, event=False, location=None) -> bool:
|
||||||
if location:
|
if location:
|
||||||
self.locations_checked.add(location)
|
self.locations_checked.add(location)
|
||||||
changed = False
|
changed = False
|
||||||
|
@ -869,10 +876,11 @@ class CollectionState(object):
|
||||||
|
|
||||||
self.stale[item.player] = True
|
self.stale[item.player] = True
|
||||||
|
|
||||||
if changed:
|
if changed and not event:
|
||||||
if not event:
|
|
||||||
self.sweep_for_events()
|
self.sweep_for_events()
|
||||||
|
|
||||||
|
return changed
|
||||||
|
|
||||||
def remove(self, item):
|
def remove(self, item):
|
||||||
if item.advancement:
|
if item.advancement:
|
||||||
to_remove = item.name
|
to_remove = item.name
|
||||||
|
@ -1077,6 +1085,7 @@ class Location():
|
||||||
shop_slot_disabled: bool = False
|
shop_slot_disabled: bool = False
|
||||||
event: bool = False
|
event: bool = False
|
||||||
locked: bool = False
|
locked: bool = False
|
||||||
|
spot_type = 'Location'
|
||||||
|
|
||||||
def __init__(self, player: int, name: str = '', address=None, crystal: bool = False,
|
def __init__(self, player: int, name: str = '', address=None, crystal: bool = False,
|
||||||
hint_text: Optional[str] = None, parent=None,
|
hint_text: Optional[str] = None, parent=None,
|
||||||
|
@ -1087,7 +1096,6 @@ class Location():
|
||||||
self.crystal = crystal
|
self.crystal = crystal
|
||||||
self.address = address
|
self.address = address
|
||||||
self.player_address = player_address
|
self.player_address = player_address
|
||||||
self.spot_type = 'Location'
|
|
||||||
self.hint_text: str = hint_text if hint_text else name
|
self.hint_text: str = hint_text if hint_text else name
|
||||||
self.recursion_count = 0
|
self.recursion_count = 0
|
||||||
self.always_allow = lambda item, state: False
|
self.always_allow = lambda item, state: False
|
||||||
|
@ -1119,11 +1127,12 @@ class Location():
|
||||||
|
|
||||||
|
|
||||||
class Item(object):
|
class Item(object):
|
||||||
|
location: Optional[Location] = None
|
||||||
|
world: Optional[World] = None
|
||||||
|
|
||||||
def __init__(self, name='', advancement=False, priority=False, type=None, code=None, pedestal_hint=None, pedestal_credit=None, sickkid_credit=None, zora_credit=None, witch_credit=None, fluteboy_credit=None, hint_text=None, player=None):
|
def __init__(self, name='', advancement=False, type=None, code=None, pedestal_hint=None, pedestal_credit=None, sickkid_credit=None, zora_credit=None, witch_credit=None, fluteboy_credit=None, hint_text=None, player=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.advancement = advancement
|
self.advancement = advancement
|
||||||
self.priority = priority
|
|
||||||
self.type = type
|
self.type = type
|
||||||
self.pedestal_hint_text = pedestal_hint
|
self.pedestal_hint_text = pedestal_hint
|
||||||
self.pedestal_credit_text = pedestal_credit
|
self.pedestal_credit_text = pedestal_credit
|
||||||
|
@ -1133,13 +1142,16 @@ class Item(object):
|
||||||
self.fluteboy_credit_text = fluteboy_credit
|
self.fluteboy_credit_text = fluteboy_credit
|
||||||
self.hint_text = hint_text
|
self.hint_text = hint_text
|
||||||
self.code = code
|
self.code = code
|
||||||
self.location = None
|
|
||||||
self.world = None
|
|
||||||
self.player = player
|
self.player = player
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.name == other.name and self.player == other.player
|
return self.name == other.name and self.player == other.player
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if other.player != self.player:
|
||||||
|
return other.player < self.player
|
||||||
|
return self.name < other.name
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.name, self.player))
|
return hash((self.name, self.player))
|
||||||
|
|
||||||
|
@ -1298,7 +1310,7 @@ class Spoiler(object):
|
||||||
'goal': self.world.goal,
|
'goal': self.world.goal,
|
||||||
'shuffle': self.world.shuffle,
|
'shuffle': self.world.shuffle,
|
||||||
'item_pool': self.world.difficulty,
|
'item_pool': self.world.difficulty,
|
||||||
'item_functionality': self.world.difficulty_adjustments,
|
'item_functionality': self.world.item_functionality,
|
||||||
'gt_crystals': self.world.crystals_needed_for_gt,
|
'gt_crystals': self.world.crystals_needed_for_gt,
|
||||||
'ganon_crystals': self.world.crystals_needed_for_ganon,
|
'ganon_crystals': self.world.crystals_needed_for_ganon,
|
||||||
'open_pyramid': self.world.open_pyramid,
|
'open_pyramid': self.world.open_pyramid,
|
||||||
|
@ -1327,7 +1339,8 @@ class Spoiler(object):
|
||||||
'shop_shuffle_slots': self.world.shop_shuffle_slots,
|
'shop_shuffle_slots': self.world.shop_shuffle_slots,
|
||||||
'shuffle_prizes': self.world.shuffle_prizes,
|
'shuffle_prizes': self.world.shuffle_prizes,
|
||||||
'sprite_pool': self.world.sprite_pool,
|
'sprite_pool': self.world.sprite_pool,
|
||||||
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss
|
'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss,
|
||||||
|
'er_seeds': self.world.er_seeds
|
||||||
}
|
}
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
|
@ -1391,6 +1404,8 @@ class Spoiler(object):
|
||||||
outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player])
|
outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player])
|
||||||
outfile.write('Item Progression: %s\n' % self.metadata['progressive'][player])
|
outfile.write('Item Progression: %s\n' % self.metadata['progressive'][player])
|
||||||
outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player])
|
outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player])
|
||||||
|
if self.metadata['shuffle'][player] != "vanilla":
|
||||||
|
outfile.write('Entrance Shuffle Seed %s\n' % self.metadata['er_seeds'][player])
|
||||||
outfile.write('Crystals required for GT: %s\n' % self.metadata['gt_crystals'][player])
|
outfile.write('Crystals required for GT: %s\n' % self.metadata['gt_crystals'][player])
|
||||||
outfile.write('Crystals required for Ganon: %s\n' % self.metadata['ganon_crystals'][player])
|
outfile.write('Crystals required for Ganon: %s\n' % self.metadata['ganon_crystals'][player])
|
||||||
outfile.write('Pyramid hole pre-opened: %s\n' % (
|
outfile.write('Pyramid hole pre-opened: %s\n' % (
|
||||||
|
|
|
@ -132,8 +132,6 @@ def fill_dungeons_restrictive(world):
|
||||||
if (item.smallkey and world.keyshuffle[item.player]) or (item.bigkey and world.bigkeyshuffle[item.player]):
|
if (item.smallkey and world.keyshuffle[item.player]) or (item.bigkey and world.bigkeyshuffle[item.player]):
|
||||||
all_state_base.collect(item, True)
|
all_state_base.collect(item, True)
|
||||||
item.advancement = True
|
item.advancement = True
|
||||||
elif (item.map and world.mapshuffle[item.player]) or (item.compass and world.compassshuffle[item.player]):
|
|
||||||
item.priority = True
|
|
||||||
|
|
||||||
dungeon_items = [item for item in get_dungeon_item_pool(world) if (((item.smallkey and not world.keyshuffle[item.player])
|
dungeon_items = [item for item in get_dungeon_item_pool(world) if (((item.smallkey and not world.keyshuffle[item.player])
|
||||||
or (item.bigkey and not world.bigkeyshuffle[item.player])
|
or (item.bigkey and not world.bigkeyshuffle[item.player])
|
||||||
|
|
|
@ -222,9 +222,16 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
Random: Picks a random value between 0 and 7 (inclusive).
|
Random: Picks a random value between 0 and 7 (inclusive).
|
||||||
0-7: Number of crystals needed
|
0-7: Number of crystals needed
|
||||||
''')
|
''')
|
||||||
parser.add_argument('--open_pyramid', default=defval(False), help='''\
|
parser.add_argument('--open_pyramid', default=defval('auto'), help='''\
|
||||||
Pre-opens the pyramid hole, this removes the Agahnim 2 requirement for it
|
Pre-opens the pyramid hole, this removes the Agahnim 2 requirement for it.
|
||||||
''', action='store_true')
|
Depending on goal, you might still need to beat Agahnim 2 in order to beat ganon.
|
||||||
|
fast ganon goals are crystals, ganontriforcehunt, localganontriforcehunt, pedestalganon
|
||||||
|
auto - Only opens pyramid hole if the goal specifies a fast ganon, and entrance shuffle
|
||||||
|
is vanilla, dungeonssimple or dungeonsfull.
|
||||||
|
goal - Opens pyramid hole if the goal specifies a fast ganon.
|
||||||
|
yes - Always opens the pyramid hole.
|
||||||
|
no - Never opens the pyramid hole.
|
||||||
|
''', choices=['auto', 'goal', 'yes', 'no'])
|
||||||
parser.add_argument('--rom', default=defval('Zelda no Densetsu - Kamigami no Triforce (Japan).sfc'),
|
parser.add_argument('--rom', default=defval('Zelda no Densetsu - Kamigami no Triforce (Japan).sfc'),
|
||||||
help='Path to an ALttP JAP(1.0) rom to use as a base.')
|
help='Path to an ALttP JAP(1.0) rom to use as a base.')
|
||||||
parser.add_argument('--loglevel', default=defval('info'), const='info', nargs='?', choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.')
|
parser.add_argument('--loglevel', default=defval('info'), const='info', nargs='?', choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.')
|
||||||
|
@ -251,6 +258,7 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
(Both can be revealed when speaking to Murahalda)
|
(Both can be revealed when speaking to Murahalda)
|
||||||
(default: %(default)s)
|
(default: %(default)s)
|
||||||
''')
|
''')
|
||||||
|
parser.add_argument('--enableflashing', help='Reenable flashing animations (unfriendly to epilepsy, always disabled in race roms)', action='store_false', dest="reduceflashing")
|
||||||
parser.add_argument('--mapshuffle', default=defval(False),
|
parser.add_argument('--mapshuffle', default=defval(False),
|
||||||
help='Maps are no longer restricted to their dungeons, but can be anywhere',
|
help='Maps are no longer restricted to their dungeons, but can be anywhere',
|
||||||
action='store_true')
|
action='store_true')
|
||||||
|
@ -377,6 +385,7 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
ret.plando_items = []
|
ret.plando_items = []
|
||||||
ret.plando_texts = {}
|
ret.plando_texts = {}
|
||||||
ret.plando_connections = []
|
ret.plando_connections = []
|
||||||
|
ret.er_seeds = {}
|
||||||
|
|
||||||
ret.glitch_boots = not ret.disable_glitch_boots
|
ret.glitch_boots = not ret.disable_glitch_boots
|
||||||
if ret.timer == "none":
|
if ret.timer == "none":
|
||||||
|
@ -407,10 +416,10 @@ def parse_arguments(argv, no_defaults=False):
|
||||||
'heartbeep', "skip_progression_balancing", "triforce_pieces_available",
|
'heartbeep', "skip_progression_balancing", "triforce_pieces_available",
|
||||||
"triforce_pieces_required", "shop_shuffle", "shop_shuffle_slots",
|
"triforce_pieces_required", "shop_shuffle", "shop_shuffle_slots",
|
||||||
"required_medallions",
|
"required_medallions",
|
||||||
"plando_items", "plando_texts", "plando_connections",
|
"plando_items", "plando_texts", "plando_connections", "er_seeds",
|
||||||
'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots', 'killable_thieves',
|
||||||
'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic',
|
'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic',
|
||||||
'restrict_dungeon_item_on_boss',
|
'restrict_dungeon_item_on_boss', 'reduceflashing',
|
||||||
'hud_palettes', 'sword_palettes', 'shield_palettes', 'link_palettes', 'triforcehud']:
|
'hud_palettes', 'sword_palettes', 'shield_palettes', 'link_palettes', 'triforcehud']:
|
||||||
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
|
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
|
||||||
if player == 1:
|
if player == 1:
|
||||||
|
|
|
@ -2054,10 +2054,11 @@ def connect_doors(world, doors, targets, player):
|
||||||
"""This works inplace"""
|
"""This works inplace"""
|
||||||
world.random.shuffle(doors)
|
world.random.shuffle(doors)
|
||||||
world.random.shuffle(targets)
|
world.random.shuffle(targets)
|
||||||
while doors:
|
placing = min(len(doors), len(targets))
|
||||||
door = doors.pop()
|
for door, target in zip(doors, targets):
|
||||||
target = targets.pop()
|
|
||||||
connect_entrance(world, door, target, player)
|
connect_entrance(world, door, target, player)
|
||||||
|
doors[:] = doors[placing:]
|
||||||
|
targets[:] = targets[placing:]
|
||||||
|
|
||||||
|
|
||||||
def skull_woods_shuffle(world, player):
|
def skull_woods_shuffle(world, player):
|
||||||
|
|
78
Fill.py
78
Fill.py
|
@ -1,5 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import typing
|
import typing
|
||||||
|
import collections
|
||||||
|
import itertools
|
||||||
|
|
||||||
from BaseClasses import CollectionState, PlandoItem, Location
|
from BaseClasses import CollectionState, PlandoItem, Location
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
|
@ -77,21 +79,14 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
||||||
# get items to distribute
|
# get items to distribute
|
||||||
world.random.shuffle(world.itempool)
|
world.random.shuffle(world.itempool)
|
||||||
progitempool = []
|
progitempool = []
|
||||||
localprioitempool = {player: [] for player in range(1, world.players + 1)}
|
|
||||||
localrestitempool = {player: [] for player in range(1, world.players + 1)}
|
localrestitempool = {player: [] for player in range(1, world.players + 1)}
|
||||||
prioitempool = []
|
|
||||||
restitempool = []
|
restitempool = []
|
||||||
|
|
||||||
for item in world.itempool:
|
for item in world.itempool:
|
||||||
if item.advancement:
|
if item.advancement:
|
||||||
progitempool.append(item)
|
progitempool.append(item)
|
||||||
elif item.name in world.local_items[item.player]:
|
elif item.name in world.local_items[item.player]:
|
||||||
if item.priority:
|
|
||||||
localprioitempool[item.player].append(item)
|
|
||||||
else:
|
|
||||||
localrestitempool[item.player].append(item)
|
localrestitempool[item.player].append(item)
|
||||||
elif item.priority:
|
|
||||||
prioitempool.append(item)
|
|
||||||
else:
|
else:
|
||||||
restitempool.append(item)
|
restitempool.append(item)
|
||||||
|
|
||||||
|
@ -141,24 +136,13 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
||||||
|
|
||||||
fill_restrictive(world, world.state, fill_locations, progitempool)
|
fill_restrictive(world, world.state, fill_locations, progitempool)
|
||||||
|
|
||||||
if any(localprioitempool.values()) or \
|
if any(localrestitempool.values()): # we need to make sure some fills are limited to certain worlds
|
||||||
any(localrestitempool.values()): # we need to make sure some fills are limited to certain worlds
|
|
||||||
local_locations = {player: [] for player in world.player_ids}
|
local_locations = {player: [] for player in world.player_ids}
|
||||||
for location in fill_locations:
|
for location in fill_locations:
|
||||||
local_locations[location.player].append(location)
|
local_locations[location.player].append(location)
|
||||||
for locations in local_locations.values():
|
for locations in local_locations.values():
|
||||||
world.random.shuffle(locations)
|
world.random.shuffle(locations)
|
||||||
|
|
||||||
for player, items in localprioitempool.items(): # items already shuffled
|
|
||||||
player_local_locations = local_locations[player]
|
|
||||||
for item_to_place in items:
|
|
||||||
if not player_local_locations:
|
|
||||||
logging.warning(f"Ran out of local locations for player {player}, "
|
|
||||||
f"cannot place {item_to_place}.")
|
|
||||||
break
|
|
||||||
spot_to_fill = player_local_locations.pop()
|
|
||||||
world.push_item(spot_to_fill, item_to_place, False)
|
|
||||||
fill_locations.remove(spot_to_fill)
|
|
||||||
for player, items in localrestitempool.items(): # items already shuffled
|
for player, items in localrestitempool.items(): # items already shuffled
|
||||||
player_local_locations = local_locations[player]
|
player_local_locations = local_locations[player]
|
||||||
for item_to_place in items:
|
for item_to_place in items:
|
||||||
|
@ -172,10 +156,8 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
||||||
|
|
||||||
world.random.shuffle(fill_locations)
|
world.random.shuffle(fill_locations)
|
||||||
|
|
||||||
prioitempool, fill_locations = fast_fill(world, prioitempool, fill_locations)
|
|
||||||
|
|
||||||
restitempool, fill_locations = fast_fill(world, restitempool, fill_locations)
|
restitempool, fill_locations = fast_fill(world, restitempool, fill_locations)
|
||||||
unplaced = [item for item in progitempool + prioitempool + restitempool]
|
unplaced = [item for item in progitempool + restitempool]
|
||||||
unfilled = [location.name for location in fill_locations]
|
unfilled = [location.name for location in fill_locations]
|
||||||
|
|
||||||
for location in fill_locations:
|
for location in fill_locations:
|
||||||
|
@ -242,7 +224,7 @@ def flood_items(world):
|
||||||
location_list = world.get_reachable_locations()
|
location_list = world.get_reachable_locations()
|
||||||
world.random.shuffle(location_list)
|
world.random.shuffle(location_list)
|
||||||
for location in location_list:
|
for location in location_list:
|
||||||
if location.item is not None and not location.item.advancement and not location.item.priority and not location.item.smallkey and not location.item.bigkey:
|
if location.item is not None and not location.item.advancement and not location.item.smallkey and not location.item.bigkey:
|
||||||
# safe to replace
|
# safe to replace
|
||||||
replace_item = location.item
|
replace_item = location.item
|
||||||
replace_item.location = None
|
replace_item.location = None
|
||||||
|
@ -263,12 +245,7 @@ def balance_multiworld_progression(world):
|
||||||
unchecked_locations = world.get_locations().copy()
|
unchecked_locations = world.get_locations().copy()
|
||||||
world.random.shuffle(unchecked_locations)
|
world.random.shuffle(unchecked_locations)
|
||||||
|
|
||||||
reachable_locations_count = {player: 0 for player in range(1, world.players + 1)}
|
reachable_locations_count = {player: 0 for player in world.player_ids}
|
||||||
|
|
||||||
def event_key(location):
|
|
||||||
return location.event and (
|
|
||||||
world.keyshuffle[location.item.player] or not location.item.smallkey) and (
|
|
||||||
world.bigkeyshuffle[location.item.player] or not location.item.bigkey)
|
|
||||||
|
|
||||||
def get_sphere_locations(sphere_state, locations):
|
def get_sphere_locations(sphere_state, locations):
|
||||||
sphere_state.sweep_for_events(key_only=True, locations=locations)
|
sphere_state.sweep_for_events(key_only=True, locations=locations)
|
||||||
|
@ -289,33 +266,38 @@ def balance_multiworld_progression(world):
|
||||||
balancing_unchecked_locations = unchecked_locations.copy()
|
balancing_unchecked_locations = unchecked_locations.copy()
|
||||||
balancing_reachables = reachable_locations_count.copy()
|
balancing_reachables = reachable_locations_count.copy()
|
||||||
balancing_sphere = sphere_locations.copy()
|
balancing_sphere = sphere_locations.copy()
|
||||||
candidate_items = []
|
candidate_items = collections.defaultdict(list)
|
||||||
while True:
|
while True:
|
||||||
for location in balancing_sphere:
|
for location in balancing_sphere:
|
||||||
if event_key(location):
|
if location.event:
|
||||||
balancing_state.collect(location.item, True, location)
|
balancing_state.collect(location.item, True, location)
|
||||||
if location.item.player in balancing_players and not location.locked:
|
player = location.item.player
|
||||||
candidate_items.append(location)
|
# only replace items that end up in another player's world
|
||||||
|
if not location.locked and player in balancing_players and location.player != player:
|
||||||
|
candidate_items[player].append(location)
|
||||||
balancing_sphere = get_sphere_locations(balancing_state, balancing_unchecked_locations)
|
balancing_sphere = get_sphere_locations(balancing_state, balancing_unchecked_locations)
|
||||||
for location in balancing_sphere:
|
for location in balancing_sphere:
|
||||||
balancing_unchecked_locations.remove(location)
|
balancing_unchecked_locations.remove(location)
|
||||||
balancing_reachables[location.player] += 1
|
balancing_reachables[location.player] += 1
|
||||||
if world.has_beaten_game(balancing_state) or all(
|
if world.has_beaten_game(balancing_state) or all(
|
||||||
[reachables >= threshold for reachables in balancing_reachables.values()]):
|
reachables >= threshold for reachables in balancing_reachables.values()):
|
||||||
break
|
break
|
||||||
elif not balancing_sphere:
|
elif not balancing_sphere:
|
||||||
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
|
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
|
||||||
|
unlocked_locations = collections.defaultdict(list)
|
||||||
unlocked_locations = [l for l in unchecked_locations if l not in balancing_unchecked_locations]
|
for l in unchecked_locations:
|
||||||
|
if l not in balancing_unchecked_locations:
|
||||||
|
unlocked_locations[l.player].append(l)
|
||||||
items_to_replace = []
|
items_to_replace = []
|
||||||
for player in balancing_players:
|
for player in balancing_players:
|
||||||
locations_to_test = [l for l in unlocked_locations if l.player == player]
|
locations_to_test = unlocked_locations[player]
|
||||||
# only replace items that end up in another player's world
|
items_to_test = candidate_items[player]
|
||||||
items_to_test = [l for l in candidate_items if l.item.player == player and l.player != player]
|
|
||||||
while items_to_test:
|
while items_to_test:
|
||||||
testing = items_to_test.pop()
|
testing = items_to_test.pop()
|
||||||
reducing_state = state.copy()
|
reducing_state = state.copy()
|
||||||
for location in [*[l for l in items_to_replace if l.item.player == player], *items_to_test]:
|
for location in itertools.chain((l for l in items_to_replace if l.item.player == player),
|
||||||
|
items_to_test):
|
||||||
|
|
||||||
reducing_state.collect(location.item, True, location)
|
reducing_state.collect(location.item, True, location)
|
||||||
|
|
||||||
reducing_state.sweep_for_events(locations=locations_to_test)
|
reducing_state.sweep_for_events(locations=locations_to_test)
|
||||||
|
@ -340,21 +322,20 @@ def balance_multiworld_progression(world):
|
||||||
new_location = replacement_locations.pop()
|
new_location = replacement_locations.pop()
|
||||||
|
|
||||||
swap_location_item(old_location, new_location)
|
swap_location_item(old_location, new_location)
|
||||||
|
|
||||||
new_location.event, old_location.event = True, False
|
|
||||||
logging.debug(f"Progression balancing moved {new_location.item} to {new_location}, "
|
logging.debug(f"Progression balancing moved {new_location.item} to {new_location}, "
|
||||||
f"displacing {old_location.item} in {old_location}")
|
f"displacing {old_location.item} into {old_location}")
|
||||||
state.collect(new_location.item, True, new_location)
|
state.collect(new_location.item, True, new_location)
|
||||||
replaced_items = True
|
replaced_items = True
|
||||||
|
|
||||||
if replaced_items:
|
if replaced_items:
|
||||||
for location in get_sphere_locations(state, [l for l in unlocked_locations if
|
unlocked = [fresh for player in balancing_players for fresh in unlocked_locations[player]]
|
||||||
l.player in balancing_players]):
|
for location in get_sphere_locations(state, unlocked):
|
||||||
unchecked_locations.remove(location)
|
unchecked_locations.remove(location)
|
||||||
reachable_locations_count[location.player] += 1
|
reachable_locations_count[location.player] += 1
|
||||||
sphere_locations.append(location)
|
sphere_locations.append(location)
|
||||||
|
|
||||||
for location in sphere_locations:
|
for location in sphere_locations:
|
||||||
if event_key(location):
|
if location.event:
|
||||||
state.collect(location.item, True, location)
|
state.collect(location.item, True, location)
|
||||||
checked_locations.extend(sphere_locations)
|
checked_locations.extend(sphere_locations)
|
||||||
|
|
||||||
|
@ -365,7 +346,7 @@ def balance_multiworld_progression(world):
|
||||||
|
|
||||||
|
|
||||||
def swap_location_item(location_1: Location, location_2: Location, check_locked=True):
|
def swap_location_item(location_1: Location, location_2: Location, check_locked=True):
|
||||||
"""Swaps Items of locations. Does NOT swap flags like event, shop_slot or locked"""
|
"""Swaps Items of locations. Does NOT swap flags like shop_slot or locked, but does swap event"""
|
||||||
if check_locked:
|
if check_locked:
|
||||||
if location_1.locked:
|
if location_1.locked:
|
||||||
logging.warning(f"Swapping {location_1}, which is marked as locked.")
|
logging.warning(f"Swapping {location_1}, which is marked as locked.")
|
||||||
|
@ -374,10 +355,11 @@ def swap_location_item(location_1: Location, location_2: Location, check_locked=
|
||||||
location_2.item, location_1.item = location_1.item, location_2.item
|
location_2.item, location_1.item = location_1.item, location_2.item
|
||||||
location_1.item.location = location_1
|
location_1.item.location = location_1
|
||||||
location_2.item.location = location_2
|
location_2.item.location = location_2
|
||||||
|
location_1.event, location_2.event = location_2.event, location_1.event
|
||||||
|
|
||||||
|
|
||||||
def distribute_planned(world):
|
def distribute_planned(world):
|
||||||
world_name_lookup = {world.player_names[player_id][0]: player_id for player_id in world.player_ids}
|
world_name_lookup = world.world_name_lookup
|
||||||
|
|
||||||
for player in world.player_ids:
|
for player in world.player_ids:
|
||||||
placement: PlandoItem
|
placement: PlandoItem
|
||||||
|
|
507
Gui.py
507
Gui.py
|
@ -14,12 +14,11 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
import ModuleUpdate
|
import ModuleUpdate
|
||||||
ModuleUpdate.update()
|
ModuleUpdate.update()
|
||||||
|
|
||||||
from AdjusterMain import adjust
|
|
||||||
from EntranceRandomizer import parse_arguments
|
from EntranceRandomizer import parse_arguments
|
||||||
from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress
|
from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress
|
||||||
from Main import main, get_seed, __version__ as MWVersion
|
from Main import main, get_seed, __version__ as MWVersion
|
||||||
from Rom import Sprite
|
from Rom import Sprite
|
||||||
from Utils import is_bundled, local_path, output_path, open_file
|
from Utils import local_path, output_path, open_file
|
||||||
|
|
||||||
|
|
||||||
def guiMain(args=None):
|
def guiMain(args=None):
|
||||||
|
@ -30,10 +29,8 @@ def guiMain(args=None):
|
||||||
|
|
||||||
notebook = ttk.Notebook(mainWindow)
|
notebook = ttk.Notebook(mainWindow)
|
||||||
randomizerWindow = ttk.Frame(notebook)
|
randomizerWindow = ttk.Frame(notebook)
|
||||||
adjustWindow = ttk.Frame(notebook)
|
|
||||||
customWindow = ttk.Frame(notebook)
|
customWindow = ttk.Frame(notebook)
|
||||||
notebook.add(randomizerWindow, text='Randomize')
|
notebook.add(randomizerWindow, text='Randomize')
|
||||||
notebook.add(adjustWindow, text='Adjust')
|
|
||||||
notebook.add(customWindow, text='Custom Items')
|
notebook.add(customWindow, text='Custom Items')
|
||||||
notebook.pack()
|
notebook.pack()
|
||||||
|
|
||||||
|
@ -57,6 +54,8 @@ def guiMain(args=None):
|
||||||
# randomizer controls
|
# randomizer controls
|
||||||
|
|
||||||
topFrame = Frame(randomizerWindow)
|
topFrame = Frame(randomizerWindow)
|
||||||
|
romFrame, romVar = get_rom_frame(topFrame)
|
||||||
|
|
||||||
rightHalfFrame = Frame(topFrame)
|
rightHalfFrame = Frame(topFrame)
|
||||||
checkBoxFrame = Frame(rightHalfFrame)
|
checkBoxFrame = Frame(rightHalfFrame)
|
||||||
|
|
||||||
|
@ -64,8 +63,13 @@ def guiMain(args=None):
|
||||||
createSpoilerCheckbutton = Checkbutton(checkBoxFrame, text="Create Spoiler Log", variable=createSpoilerVar)
|
createSpoilerCheckbutton = Checkbutton(checkBoxFrame, text="Create Spoiler Log", variable=createSpoilerVar)
|
||||||
suppressRomVar = IntVar()
|
suppressRomVar = IntVar()
|
||||||
suppressRomCheckbutton = Checkbutton(checkBoxFrame, text="Do not create patched Rom", variable=suppressRomVar)
|
suppressRomCheckbutton = Checkbutton(checkBoxFrame, text="Do not create patched Rom", variable=suppressRomVar)
|
||||||
openpyramidVar = IntVar()
|
openpyramidFrame = Frame(checkBoxFrame)
|
||||||
openpyramidCheckbutton = Checkbutton(checkBoxFrame, text="Pre-open Pyramid Hole", variable=openpyramidVar)
|
openpyramidVar = StringVar()
|
||||||
|
openpyramidVar.set('auto')
|
||||||
|
openpyramidOptionMenu = OptionMenu(openpyramidFrame, openpyramidVar, 'auto', 'goal', 'yes', 'no')
|
||||||
|
openpyramidLabel = Label(openpyramidFrame, text='Pre-open Pyramid Hole')
|
||||||
|
openpyramidLabel.pack(side=LEFT)
|
||||||
|
openpyramidOptionMenu.pack(side=LEFT)
|
||||||
mcsbshuffleFrame = Frame(checkBoxFrame)
|
mcsbshuffleFrame = Frame(checkBoxFrame)
|
||||||
mcsbLabel = Label(mcsbshuffleFrame, text="Shuffle: ")
|
mcsbLabel = Label(mcsbshuffleFrame, text="Shuffle: ")
|
||||||
|
|
||||||
|
@ -102,7 +106,7 @@ def guiMain(args=None):
|
||||||
|
|
||||||
createSpoilerCheckbutton.pack(expand=True, anchor=W)
|
createSpoilerCheckbutton.pack(expand=True, anchor=W)
|
||||||
suppressRomCheckbutton.pack(expand=True, anchor=W)
|
suppressRomCheckbutton.pack(expand=True, anchor=W)
|
||||||
openpyramidCheckbutton.pack(expand=True, anchor=W)
|
openpyramidFrame.pack(expand=True, anchor=W)
|
||||||
mcsbshuffleFrame.pack(expand=True, anchor=W)
|
mcsbshuffleFrame.pack(expand=True, anchor=W)
|
||||||
mcsbLabel.grid(row=0, column=0)
|
mcsbLabel.grid(row=0, column=0)
|
||||||
mapshuffleCheckbutton.grid(row=0, column=1)
|
mapshuffleCheckbutton.grid(row=0, column=1)
|
||||||
|
@ -114,154 +118,9 @@ def guiMain(args=None):
|
||||||
hintsCheckbutton.pack(expand=True, anchor=W)
|
hintsCheckbutton.pack(expand=True, anchor=W)
|
||||||
tileShuffleButton.pack(expand=True, anchor=W)
|
tileShuffleButton.pack(expand=True, anchor=W)
|
||||||
|
|
||||||
|
|
||||||
romOptionsFrame = LabelFrame(rightHalfFrame, text="Rom options")
|
|
||||||
romOptionsFrame.columnconfigure(0, weight=1)
|
|
||||||
romOptionsFrame.columnconfigure(1, weight=1)
|
|
||||||
for i in range(5):
|
|
||||||
romOptionsFrame.rowconfigure(i, weight=1)
|
|
||||||
|
|
||||||
disableMusicVar = IntVar()
|
|
||||||
disableMusicCheckbutton = Checkbutton(romOptionsFrame, text="Disable music", variable=disableMusicVar)
|
|
||||||
disableMusicCheckbutton.grid(row=0, column=0, sticky=E)
|
|
||||||
|
|
||||||
spriteDialogFrame = Frame(romOptionsFrame)
|
|
||||||
spriteDialogFrame.grid(row=0, column=1)
|
|
||||||
baseSpriteLabel = Label(spriteDialogFrame, text='Sprite:')
|
|
||||||
|
|
||||||
spriteNameVar = StringVar()
|
|
||||||
sprite = None
|
|
||||||
def set_sprite(sprite_param):
|
|
||||||
nonlocal sprite
|
|
||||||
if isinstance(sprite_param, str):
|
|
||||||
sprite = sprite_param
|
|
||||||
spriteNameVar.set(sprite_param)
|
|
||||||
elif sprite_param is None or not sprite_param.valid:
|
|
||||||
sprite = None
|
|
||||||
spriteNameVar.set('(unchanged)')
|
|
||||||
else:
|
|
||||||
sprite = sprite_param
|
|
||||||
spriteNameVar.set(sprite.name)
|
|
||||||
|
|
||||||
set_sprite(None)
|
|
||||||
spriteNameVar.set('(unchanged)')
|
|
||||||
spriteEntry = Label(spriteDialogFrame, textvariable=spriteNameVar)
|
|
||||||
|
|
||||||
def SpriteSelect():
|
|
||||||
SpriteSelector(mainWindow, set_sprite)
|
|
||||||
|
|
||||||
spriteSelectButton = Button(spriteDialogFrame, text='...', command=SpriteSelect)
|
|
||||||
|
|
||||||
baseSpriteLabel.pack(side=LEFT)
|
|
||||||
spriteEntry.pack(side=LEFT)
|
|
||||||
spriteSelectButton.pack(side=LEFT)
|
|
||||||
|
|
||||||
quickSwapVar = IntVar(value=1)
|
|
||||||
quickSwapCheckbutton = Checkbutton(romOptionsFrame, text="L/R Quickswapping", variable=quickSwapVar)
|
|
||||||
quickSwapCheckbutton.grid(row=1, column=0, sticky=E)
|
|
||||||
|
|
||||||
fastMenuFrame = Frame(romOptionsFrame)
|
|
||||||
fastMenuFrame.grid(row=1, column=1, sticky=E)
|
|
||||||
fastMenuLabel = Label(fastMenuFrame, text='Menu speed')
|
|
||||||
fastMenuLabel.pack(side=LEFT)
|
|
||||||
fastMenuVar = StringVar()
|
|
||||||
fastMenuVar.set('normal')
|
|
||||||
fastMenuOptionMenu = OptionMenu(fastMenuFrame, fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half')
|
|
||||||
fastMenuOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
heartcolorFrame = Frame(romOptionsFrame)
|
|
||||||
heartcolorFrame.grid(row=2, column=0, sticky=E)
|
|
||||||
heartcolorLabel = Label(heartcolorFrame, text='Heart color')
|
|
||||||
heartcolorLabel.pack(side=LEFT)
|
|
||||||
heartcolorVar = StringVar()
|
|
||||||
heartcolorVar.set('red')
|
|
||||||
heartcolorOptionMenu = OptionMenu(heartcolorFrame, heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random')
|
|
||||||
heartcolorOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
heartbeepFrame = Frame(romOptionsFrame)
|
|
||||||
heartbeepFrame.grid(row=2, column=1, sticky=E)
|
|
||||||
heartbeepLabel = Label(heartbeepFrame, text='Heartbeep')
|
|
||||||
heartbeepLabel.pack(side=LEFT)
|
|
||||||
heartbeepVar = StringVar()
|
|
||||||
heartbeepVar.set('normal')
|
|
||||||
heartbeepOptionMenu = OptionMenu(heartbeepFrame, heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off')
|
|
||||||
heartbeepOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
owPalettesFrame = Frame(romOptionsFrame)
|
|
||||||
owPalettesFrame.grid(row=3, column=0, sticky=E)
|
|
||||||
owPalettesLabel = Label(owPalettesFrame, text='Overworld palettes')
|
|
||||||
owPalettesLabel.pack(side=LEFT)
|
|
||||||
owPalettesVar = StringVar()
|
|
||||||
owPalettesVar.set('default')
|
|
||||||
owPalettesOptionMenu = OptionMenu(owPalettesFrame, owPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
owPalettesOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
uwPalettesFrame = Frame(romOptionsFrame)
|
|
||||||
uwPalettesFrame.grid(row=3, column=1, sticky=E)
|
|
||||||
uwPalettesLabel = Label(uwPalettesFrame, text='Dungeon palettes')
|
|
||||||
uwPalettesLabel.pack(side=LEFT)
|
|
||||||
uwPalettesVar = StringVar()
|
|
||||||
uwPalettesVar.set('default')
|
|
||||||
uwPalettesOptionMenu = OptionMenu(uwPalettesFrame, uwPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
uwPalettesOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
hudPalettesFrame = Frame(romOptionsFrame)
|
|
||||||
hudPalettesFrame.grid(row=4, column=0, sticky=E)
|
|
||||||
hudPalettesLabel = Label(hudPalettesFrame, text='HUD palettes')
|
|
||||||
hudPalettesLabel.pack(side=LEFT)
|
|
||||||
hudPalettesVar = StringVar()
|
|
||||||
hudPalettesVar.set('default')
|
|
||||||
hudPalettesOptionMenu = OptionMenu(hudPalettesFrame, hudPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
hudPalettesOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
swordPalettesFrame = Frame(romOptionsFrame)
|
|
||||||
swordPalettesFrame.grid(row=4, column=1, sticky=E)
|
|
||||||
swordPalettesLabel = Label(swordPalettesFrame, text='Sword palettes')
|
|
||||||
swordPalettesLabel.pack(side=LEFT)
|
|
||||||
swordPalettesVar = StringVar()
|
|
||||||
swordPalettesVar.set('default')
|
|
||||||
swordPalettesOptionMenu = OptionMenu(swordPalettesFrame, swordPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
swordPalettesOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
shieldPalettesFrame = Frame(romOptionsFrame)
|
|
||||||
shieldPalettesFrame.grid(row=5, column=0, sticky=E)
|
|
||||||
shieldPalettesLabel = Label(shieldPalettesFrame, text='Shield palettes')
|
|
||||||
shieldPalettesLabel.pack(side=LEFT)
|
|
||||||
shieldPalettesVar = StringVar()
|
|
||||||
shieldPalettesVar.set('default')
|
|
||||||
shieldPalettesOptionMenu = OptionMenu(shieldPalettesFrame, shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
shieldPalettesOptionMenu.pack(side=LEFT)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
romDialogFrame = Frame(romOptionsFrame)
|
|
||||||
romDialogFrame.grid(row=6, column=0, columnspan=2, sticky=W+E)
|
|
||||||
|
|
||||||
baseRomLabel = Label(romDialogFrame, text='Base Rom: ')
|
|
||||||
romVar = StringVar(value="Zelda no Densetsu - Kamigami no Triforce (Japan).sfc")
|
|
||||||
romEntry = Entry(romDialogFrame, textvariable=romVar)
|
|
||||||
|
|
||||||
def RomSelect():
|
|
||||||
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")])
|
|
||||||
import Patch
|
|
||||||
try:
|
|
||||||
Patch.get_base_rom_bytes(rom) # throws error on checksum fail
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception(e)
|
|
||||||
messagebox.showerror(title="Error while reading ROM", message=str(e))
|
|
||||||
else:
|
|
||||||
romVar.set(rom)
|
|
||||||
romSelectButton['state'] = "disabled"
|
|
||||||
romSelectButton["text"] = "ROM verified"
|
|
||||||
romSelectButton = Button(romDialogFrame, text='Select Rom', command=RomSelect)
|
|
||||||
|
|
||||||
baseRomLabel.pack(side=LEFT)
|
|
||||||
romEntry.pack(side=LEFT, expand=True, fill=X)
|
|
||||||
romSelectButton.pack(side=LEFT)
|
|
||||||
|
|
||||||
checkBoxFrame.pack(side=TOP, anchor=W, padx=5, pady=10)
|
checkBoxFrame.pack(side=TOP, anchor=W, padx=5, pady=10)
|
||||||
|
|
||||||
|
romOptionsFrame, rom_vars, set_sprite = get_rom_options_frame(rightHalfFrame)
|
||||||
romOptionsFrame.pack(expand=True, fill=BOTH, padx=3)
|
romOptionsFrame.pack(expand=True, fill=BOTH, padx=3)
|
||||||
|
|
||||||
drowDownFrame = Frame(topFrame)
|
drowDownFrame = Frame(topFrame)
|
||||||
|
@ -377,7 +236,8 @@ def guiMain(args=None):
|
||||||
shuffleVar.set('vanilla')
|
shuffleVar.set('vanilla')
|
||||||
shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'crossed',
|
shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'crossed',
|
||||||
'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy',
|
'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy',
|
||||||
'dungeonsfull', 'dungeonssimple')
|
'dungeonsfull', 'dungeonssimple', "same simple", "same restricted", "same full",
|
||||||
|
"same crossed", "same insanity", "same dungeonsfull", "same dungeonssimple")
|
||||||
shuffleOptionMenu.pack(side=RIGHT)
|
shuffleOptionMenu.pack(side=RIGHT)
|
||||||
shuffleLabel = Label(shuffleFrame, text='Entrance shuffle')
|
shuffleLabel = Label(shuffleFrame, text='Entrance shuffle')
|
||||||
shuffleLabel.pack(side=LEFT)
|
shuffleLabel.pack(side=LEFT)
|
||||||
|
@ -558,25 +418,29 @@ def guiMain(args=None):
|
||||||
guiargs.accessibility = accessibilityVar.get()
|
guiargs.accessibility = accessibilityVar.get()
|
||||||
guiargs.algorithm = algorithmVar.get()
|
guiargs.algorithm = algorithmVar.get()
|
||||||
guiargs.shuffle = shuffleVar.get()
|
guiargs.shuffle = shuffleVar.get()
|
||||||
guiargs.heartbeep = heartbeepVar.get()
|
if "same " in guiargs.shuffle:
|
||||||
guiargs.heartcolor = heartcolorVar.get()
|
guiargs.shuffle = guiargs.shuffle[5:] + "-" + str(seedVar.get() if seedVar.get() else
|
||||||
guiargs.fastmenu = fastMenuVar.get()
|
random.randint(0, 2**64))
|
||||||
|
guiargs.heartbeep = rom_vars.heartbeepVar.get()
|
||||||
|
guiargs.heartcolor = rom_vars.heartcolorVar.get()
|
||||||
|
guiargs.fastmenu = rom_vars.fastMenuVar.get()
|
||||||
guiargs.create_spoiler = bool(createSpoilerVar.get())
|
guiargs.create_spoiler = bool(createSpoilerVar.get())
|
||||||
guiargs.skip_playthrough = not bool(createSpoilerVar.get())
|
guiargs.skip_playthrough = not bool(createSpoilerVar.get())
|
||||||
guiargs.suppress_rom = bool(suppressRomVar.get())
|
guiargs.suppress_rom = bool(suppressRomVar.get())
|
||||||
guiargs.open_pyramid = bool(openpyramidVar.get())
|
guiargs.open_pyramid = openpyramidVar.get()
|
||||||
guiargs.mapshuffle = bool(mapshuffleVar.get())
|
guiargs.mapshuffle = bool(mapshuffleVar.get())
|
||||||
guiargs.compassshuffle = bool(compassshuffleVar.get())
|
guiargs.compassshuffle = bool(compassshuffleVar.get())
|
||||||
guiargs.keyshuffle = {"on": True, "universal": "universal", "off": False}[keyshuffleVar.get()]
|
guiargs.keyshuffle = {"on": True, "universal": "universal", "off": False}[keyshuffleVar.get()]
|
||||||
guiargs.bigkeyshuffle = bool(bigkeyshuffleVar.get())
|
guiargs.bigkeyshuffle = bool(bigkeyshuffleVar.get())
|
||||||
guiargs.retro = bool(retroVar.get())
|
guiargs.retro = bool(retroVar.get())
|
||||||
guiargs.quickswap = bool(quickSwapVar.get())
|
guiargs.quickswap = bool(rom_vars.quickSwapVar.get())
|
||||||
guiargs.disablemusic = bool(disableMusicVar.get())
|
guiargs.disablemusic = bool(rom_vars.disableMusicVar.get())
|
||||||
guiargs.ow_palettes = owPalettesVar.get()
|
guiargs.reduceflashing = bool(rom_vars.disableFlashingVar.get())
|
||||||
guiargs.uw_palettes = uwPalettesVar.get()
|
guiargs.ow_palettes = rom_vars.owPalettesVar.get()
|
||||||
guiargs.hud_palettes = hudPalettesVar.get()
|
guiargs.uw_palettes = rom_vars.uwPalettesVar.get()
|
||||||
guiargs.sword_palettes = swordPalettesVar.get()
|
guiargs.hud_palettes = rom_vars.hudPalettesVar.get()
|
||||||
guiargs.shield_palettes = shieldPalettesVar.get()
|
guiargs.sword_palettes = rom_vars.swordPalettesVar.get()
|
||||||
|
guiargs.shield_palettes = rom_vars.shieldPalettesVar.get()
|
||||||
guiargs.shuffleganon = bool(shuffleGanonVar.get())
|
guiargs.shuffleganon = bool(shuffleGanonVar.get())
|
||||||
guiargs.hints = bool(hintsVar.get())
|
guiargs.hints = bool(hintsVar.get())
|
||||||
guiargs.enemizercli = enemizerCLIpathVar.get()
|
guiargs.enemizercli = enemizerCLIpathVar.get()
|
||||||
|
@ -636,7 +500,7 @@ def guiMain(args=None):
|
||||||
int(rupoorcostVar.get()), int(triforceVar.get())]
|
int(rupoorcostVar.get()), int(triforceVar.get())]
|
||||||
guiargs.rom = romVar.get()
|
guiargs.rom = romVar.get()
|
||||||
guiargs.create_diff = patchesVar.get()
|
guiargs.create_diff = patchesVar.get()
|
||||||
guiargs.sprite = sprite
|
guiargs.sprite = rom_vars.sprite
|
||||||
# get default values for missing parameters
|
# get default values for missing parameters
|
||||||
for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items():
|
for k,v in vars(parse_arguments(['--multi', str(guiargs.multi)])).items():
|
||||||
if k not in vars(guiargs):
|
if k not in vars(guiargs):
|
||||||
|
@ -684,150 +548,6 @@ def guiMain(args=None):
|
||||||
enemizerFrame.pack(side=BOTTOM, fill=BOTH)
|
enemizerFrame.pack(side=BOTTOM, fill=BOTH)
|
||||||
shopframe.pack(side=BOTTOM, expand=True, fill=X)
|
shopframe.pack(side=BOTTOM, expand=True, fill=X)
|
||||||
|
|
||||||
# Adjuster Controls
|
|
||||||
|
|
||||||
topFrame2 = Frame(adjustWindow)
|
|
||||||
rightHalfFrame2 = Frame(topFrame2)
|
|
||||||
checkBoxFrame2 = Frame(rightHalfFrame2)
|
|
||||||
|
|
||||||
quickSwapCheckbutton2 = Checkbutton(checkBoxFrame2, text="L/R Item quickswapping", variable=quickSwapVar)
|
|
||||||
disableMusicCheckbutton2 = Checkbutton(checkBoxFrame2, text="Disable game music", variable=disableMusicVar)
|
|
||||||
|
|
||||||
quickSwapCheckbutton2.pack(expand=True, anchor=W)
|
|
||||||
disableMusicCheckbutton2.pack(expand=True, anchor=W)
|
|
||||||
|
|
||||||
fileDialogFrame2 = Frame(rightHalfFrame2)
|
|
||||||
|
|
||||||
romDialogFrame2 = Frame(fileDialogFrame2)
|
|
||||||
baseRomLabel2 = Label(romDialogFrame2, text='Rom to adjust')
|
|
||||||
romVar2 = StringVar()
|
|
||||||
romEntry2 = Entry(romDialogFrame2, textvariable=romVar2)
|
|
||||||
|
|
||||||
def RomSelect2():
|
|
||||||
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc", ".bmbp")), ("All Files", "*")])
|
|
||||||
romVar2.set(rom)
|
|
||||||
romSelectButton2 = Button(romDialogFrame2, text='Select Rom', command=RomSelect2)
|
|
||||||
|
|
||||||
baseRomLabel2.pack(side=LEFT)
|
|
||||||
romEntry2.pack(side=LEFT)
|
|
||||||
romSelectButton2.pack(side=LEFT)
|
|
||||||
|
|
||||||
spriteDialogFrame2 = Frame(fileDialogFrame2)
|
|
||||||
baseSpriteLabel2 = Label(spriteDialogFrame2, text='Link Sprite')
|
|
||||||
spriteEntry2 = Label(spriteDialogFrame2, textvariable=spriteNameVar)
|
|
||||||
|
|
||||||
def SpriteSelectAdjuster():
|
|
||||||
SpriteSelector(mainWindow, set_sprite, adjuster=True)
|
|
||||||
|
|
||||||
spriteSelectButton2 = Button(spriteDialogFrame2, text='Select Sprite', command=SpriteSelectAdjuster)
|
|
||||||
|
|
||||||
baseSpriteLabel2.pack(side=LEFT)
|
|
||||||
spriteEntry2.pack(side=LEFT)
|
|
||||||
spriteSelectButton2.pack(side=LEFT)
|
|
||||||
|
|
||||||
romDialogFrame2.pack()
|
|
||||||
spriteDialogFrame2.pack()
|
|
||||||
|
|
||||||
checkBoxFrame2.pack()
|
|
||||||
fileDialogFrame2.pack()
|
|
||||||
|
|
||||||
drowDownFrame2 = Frame(topFrame2)
|
|
||||||
heartbeepFrame2 = Frame(drowDownFrame2)
|
|
||||||
heartbeepOptionMenu2 = OptionMenu(heartbeepFrame2, heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off')
|
|
||||||
heartbeepOptionMenu2.pack(side=RIGHT)
|
|
||||||
heartbeepLabel2 = Label(heartbeepFrame2, text='Heartbeep sound rate')
|
|
||||||
heartbeepLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
heartcolorFrame2 = Frame(drowDownFrame2)
|
|
||||||
heartcolorOptionMenu2 = OptionMenu(heartcolorFrame2, heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random')
|
|
||||||
heartcolorOptionMenu2.pack(side=RIGHT)
|
|
||||||
heartcolorLabel2 = Label(heartcolorFrame2, text='Heart color')
|
|
||||||
heartcolorLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
fastMenuFrame2 = Frame(drowDownFrame2)
|
|
||||||
fastMenuOptionMenu2 = OptionMenu(fastMenuFrame2, fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half')
|
|
||||||
fastMenuOptionMenu2.pack(side=RIGHT)
|
|
||||||
fastMenuLabel2 = Label(fastMenuFrame2, text='Menu speed')
|
|
||||||
fastMenuLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
owPalettesFrame2 = Frame(drowDownFrame2)
|
|
||||||
owPalettesOptionMenu2 = OptionMenu(owPalettesFrame2, owPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
owPalettesOptionMenu2.pack(side=RIGHT)
|
|
||||||
owPalettesLabel2 = Label(owPalettesFrame2, text='Overworld palettes')
|
|
||||||
owPalettesLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
uwPalettesFrame2 = Frame(drowDownFrame2)
|
|
||||||
uwPalettesOptionMenu2 = OptionMenu(uwPalettesFrame2, uwPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
uwPalettesOptionMenu2.pack(side=RIGHT)
|
|
||||||
uwPalettesLabel2 = Label(uwPalettesFrame2, text='Dungeon palettes')
|
|
||||||
uwPalettesLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
hudPalettesFrame2 = Frame(drowDownFrame2)
|
|
||||||
hudPalettesOptionMenu2 = OptionMenu(hudPalettesFrame2, hudPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
hudPalettesOptionMenu2.pack(side=RIGHT)
|
|
||||||
hudPalettesLabel2 = Label(hudPalettesFrame2, text='HUD palettes')
|
|
||||||
hudPalettesLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
swordPalettesFrame2 = Frame(drowDownFrame2)
|
|
||||||
swordPalettesOptionMenu2 = OptionMenu(swordPalettesFrame2, swordPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
swordPalettesOptionMenu2.pack(side=RIGHT)
|
|
||||||
swordPalettesLabel2 = Label(swordPalettesFrame2, text='Sword palettes')
|
|
||||||
swordPalettesLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
shieldPalettesFrame2 = Frame(drowDownFrame2)
|
|
||||||
shieldPalettesOptionMenu2 = OptionMenu(shieldPalettesFrame2, shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
|
||||||
shieldPalettesOptionMenu2.pack(side=RIGHT)
|
|
||||||
shieldPalettesLabel2 = Label(shieldPalettesFrame2, text='Shield palettes')
|
|
||||||
shieldPalettesLabel2.pack(side=LEFT)
|
|
||||||
|
|
||||||
heartbeepFrame2.pack(expand=True, anchor=E)
|
|
||||||
heartcolorFrame2.pack(expand=True, anchor=E)
|
|
||||||
fastMenuFrame2.pack(expand=True, anchor=E)
|
|
||||||
owPalettesFrame2.pack(expand=True, anchor=E)
|
|
||||||
uwPalettesFrame2.pack(expand=True, anchor=E)
|
|
||||||
hudPalettesFrame2.pack(expand=True, anchor=E)
|
|
||||||
swordPalettesFrame2.pack(expand=True, anchor=E)
|
|
||||||
shieldPalettesFrame2.pack(expand=True, anchor=E)
|
|
||||||
|
|
||||||
bottomFrame2 = Frame(topFrame2)
|
|
||||||
|
|
||||||
def adjustRom():
|
|
||||||
guiargs = Namespace()
|
|
||||||
guiargs.heartbeep = heartbeepVar.get()
|
|
||||||
guiargs.heartcolor = heartcolorVar.get()
|
|
||||||
guiargs.fastmenu = fastMenuVar.get()
|
|
||||||
guiargs.ow_palettes = owPalettesVar.get()
|
|
||||||
guiargs.uw_palettes = uwPalettesVar.get()
|
|
||||||
guiargs.hud_palettes = hudPalettesVar.get()
|
|
||||||
guiargs.sword_palettes = swordPalettesVar.get()
|
|
||||||
guiargs.shield_palettes = shieldPalettesVar.get()
|
|
||||||
guiargs.quickswap = bool(quickSwapVar.get())
|
|
||||||
guiargs.disablemusic = bool(disableMusicVar.get())
|
|
||||||
guiargs.rom = romVar2.get()
|
|
||||||
guiargs.baserom = romVar.get()
|
|
||||||
guiargs.sprite = sprite
|
|
||||||
try:
|
|
||||||
guiargs, path = adjust(args=guiargs)
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception(e)
|
|
||||||
messagebox.showerror(title="Error while adjusting Rom", message=str(e))
|
|
||||||
else:
|
|
||||||
messagebox.showinfo(title="Success", message="Rom patched successfully")
|
|
||||||
from Utils import persistent_store
|
|
||||||
from Rom import Sprite
|
|
||||||
if isinstance(guiargs.sprite, Sprite):
|
|
||||||
guiargs.sprite = guiargs.sprite.name
|
|
||||||
persistent_store("adjuster", "last_settings_3", guiargs)
|
|
||||||
|
|
||||||
adjustButton = Button(bottomFrame2, text='Adjust Rom', command=adjustRom)
|
|
||||||
|
|
||||||
adjustButton.pack(side=LEFT, padx=(5, 0))
|
|
||||||
|
|
||||||
drowDownFrame2.pack(side=LEFT, pady=(0, 40))
|
|
||||||
rightHalfFrame2.pack(side=RIGHT)
|
|
||||||
topFrame2.pack(side=TOP, pady=70)
|
|
||||||
bottomFrame2.pack(side=BOTTOM, pady=(180, 0))
|
|
||||||
|
|
||||||
# Custom Controls
|
# Custom Controls
|
||||||
|
|
||||||
topFrame3 = Frame(customWindow)
|
topFrame3 = Frame(customWindow)
|
||||||
|
@ -1485,8 +1205,9 @@ def guiMain(args=None):
|
||||||
keyshuffleVar.set(args.keyshuffle)
|
keyshuffleVar.set(args.keyshuffle)
|
||||||
bigkeyshuffleVar.set(args.bigkeyshuffle)
|
bigkeyshuffleVar.set(args.bigkeyshuffle)
|
||||||
retroVar.set(args.retro)
|
retroVar.set(args.retro)
|
||||||
quickSwapVar.set(int(args.quickswap))
|
rom_vars.quickSwapVar.set(int(args.quickswap))
|
||||||
disableMusicVar.set(int(args.disablemusic))
|
rom_vars.disableMusicVar.set(int(args.disablemusic))
|
||||||
|
rom_vars.disableFlashingVar.set(int(args.reduceflashing))
|
||||||
if args.count:
|
if args.count:
|
||||||
countVar.set(str(args.count))
|
countVar.set(str(args.count))
|
||||||
if args.seed:
|
if args.seed:
|
||||||
|
@ -1507,10 +1228,10 @@ def guiMain(args=None):
|
||||||
crystalsGanonVar.set(args.crystals_ganon)
|
crystalsGanonVar.set(args.crystals_ganon)
|
||||||
algorithmVar.set(args.algorithm)
|
algorithmVar.set(args.algorithm)
|
||||||
shuffleVar.set(args.shuffle)
|
shuffleVar.set(args.shuffle)
|
||||||
heartbeepVar.set(args.heartbeep)
|
rom_vars.heartbeepVar.set(args.heartbeep)
|
||||||
fastMenuVar.set(args.fastmenu)
|
rom_vars.fastMenuVar.set(args.fastmenu)
|
||||||
logicVar.set(args.logic)
|
logicVar.set(args.logic)
|
||||||
romVar.set(args.rom)
|
rom_vars.romVar.set(args.rom)
|
||||||
shuffleGanonVar.set(args.shuffleganon)
|
shuffleGanonVar.set(args.shuffleganon)
|
||||||
hintsVar.set(args.hints)
|
hintsVar.set(args.hints)
|
||||||
if args.sprite is not None:
|
if args.sprite is not None:
|
||||||
|
@ -1518,10 +1239,164 @@ def guiMain(args=None):
|
||||||
|
|
||||||
mainWindow.mainloop()
|
mainWindow.mainloop()
|
||||||
|
|
||||||
|
def get_rom_frame(parent=None):
|
||||||
|
romFrame = Frame(parent)
|
||||||
|
baseRomLabel = Label(romFrame, text='LttP Base Rom: ')
|
||||||
|
romVar = StringVar(value="Zelda no Densetsu - Kamigami no Triforce (Japan).sfc")
|
||||||
|
romEntry = Entry(romFrame, textvariable=romVar)
|
||||||
|
|
||||||
|
def RomSelect():
|
||||||
|
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")])
|
||||||
|
import Patch
|
||||||
|
try:
|
||||||
|
Patch.get_base_rom_bytes(rom) # throws error on checksum fail
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(e)
|
||||||
|
messagebox.showerror(title="Error while reading ROM", message=str(e))
|
||||||
|
else:
|
||||||
|
romVar.set(rom)
|
||||||
|
romSelectButton['state'] = "disabled"
|
||||||
|
romSelectButton["text"] = "ROM verified"
|
||||||
|
romSelectButton = Button(romFrame, text='Select Rom', command=RomSelect)
|
||||||
|
|
||||||
|
baseRomLabel.pack(side=LEFT)
|
||||||
|
romEntry.pack(side=LEFT, expand=True, fill=X)
|
||||||
|
romSelectButton.pack(side=LEFT)
|
||||||
|
romFrame.pack(side=TOP, expand=True, fill=X)
|
||||||
|
|
||||||
|
return romFrame, romVar
|
||||||
|
|
||||||
|
|
||||||
|
def get_rom_options_frame(parent=None):
|
||||||
|
romOptionsFrame = LabelFrame(parent, text="Rom options")
|
||||||
|
romOptionsFrame.columnconfigure(0, weight=1)
|
||||||
|
romOptionsFrame.columnconfigure(1, weight=1)
|
||||||
|
for i in range(5):
|
||||||
|
romOptionsFrame.rowconfigure(i, weight=1)
|
||||||
|
vars = Namespace()
|
||||||
|
|
||||||
|
vars.disableMusicVar = IntVar()
|
||||||
|
disableMusicCheckbutton = Checkbutton(romOptionsFrame, text="Disable music", variable=vars.disableMusicVar)
|
||||||
|
disableMusicCheckbutton.grid(row=0, column=0, sticky=E)
|
||||||
|
|
||||||
|
vars.disableFlashingVar = IntVar(value=1)
|
||||||
|
disableFlashingCheckbutton = Checkbutton(romOptionsFrame, text="Disable flashing (anti-epilepsy)", variable=vars.disableFlashingVar)
|
||||||
|
disableFlashingCheckbutton.grid(row=6, column=0, sticky=E)
|
||||||
|
|
||||||
|
spriteDialogFrame = Frame(romOptionsFrame)
|
||||||
|
spriteDialogFrame.grid(row=0, column=1)
|
||||||
|
baseSpriteLabel = Label(spriteDialogFrame, text='Sprite:')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vars.spriteNameVar = StringVar()
|
||||||
|
vars.sprite = None
|
||||||
|
def set_sprite(sprite_param):
|
||||||
|
nonlocal vars
|
||||||
|
if isinstance(sprite_param, str):
|
||||||
|
vars.sprite = sprite_param
|
||||||
|
vars.spriteNameVar.set(sprite_param)
|
||||||
|
elif sprite_param is None or not sprite_param.valid:
|
||||||
|
vars.sprite = None
|
||||||
|
vars.spriteNameVar.set('(unchanged)')
|
||||||
|
else:
|
||||||
|
vars.sprite = sprite_param
|
||||||
|
vars.spriteNameVar.set(vars.sprite.name)
|
||||||
|
|
||||||
|
set_sprite(None)
|
||||||
|
vars.spriteNameVar.set('(unchanged)')
|
||||||
|
spriteEntry = Label(spriteDialogFrame, textvariable=vars.spriteNameVar)
|
||||||
|
|
||||||
|
def SpriteSelect():
|
||||||
|
SpriteSelector(parent, set_sprite)
|
||||||
|
|
||||||
|
spriteSelectButton = Button(spriteDialogFrame, text='...', command=SpriteSelect)
|
||||||
|
|
||||||
|
baseSpriteLabel.pack(side=LEFT)
|
||||||
|
spriteEntry.pack(side=LEFT)
|
||||||
|
spriteSelectButton.pack(side=LEFT)
|
||||||
|
|
||||||
|
vars.quickSwapVar = IntVar(value=1)
|
||||||
|
quickSwapCheckbutton = Checkbutton(romOptionsFrame, text="L/R Quickswapping", variable=vars.quickSwapVar)
|
||||||
|
quickSwapCheckbutton.grid(row=1, column=0, sticky=E)
|
||||||
|
|
||||||
|
fastMenuFrame = Frame(romOptionsFrame)
|
||||||
|
fastMenuFrame.grid(row=1, column=1, sticky=E)
|
||||||
|
fastMenuLabel = Label(fastMenuFrame, text='Menu speed')
|
||||||
|
fastMenuLabel.pack(side=LEFT)
|
||||||
|
vars.fastMenuVar = StringVar()
|
||||||
|
vars.fastMenuVar.set('normal')
|
||||||
|
fastMenuOptionMenu = OptionMenu(fastMenuFrame, vars.fastMenuVar, 'normal', 'instant', 'double', 'triple', 'quadruple', 'half')
|
||||||
|
fastMenuOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
heartcolorFrame = Frame(romOptionsFrame)
|
||||||
|
heartcolorFrame.grid(row=2, column=0, sticky=E)
|
||||||
|
heartcolorLabel = Label(heartcolorFrame, text='Heart color')
|
||||||
|
heartcolorLabel.pack(side=LEFT)
|
||||||
|
vars.heartcolorVar = StringVar()
|
||||||
|
vars.heartcolorVar.set('red')
|
||||||
|
heartcolorOptionMenu = OptionMenu(heartcolorFrame, vars.heartcolorVar, 'red', 'blue', 'green', 'yellow', 'random')
|
||||||
|
heartcolorOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
heartbeepFrame = Frame(romOptionsFrame)
|
||||||
|
heartbeepFrame.grid(row=2, column=1, sticky=E)
|
||||||
|
heartbeepLabel = Label(heartbeepFrame, text='Heartbeep')
|
||||||
|
heartbeepLabel.pack(side=LEFT)
|
||||||
|
vars.heartbeepVar = StringVar()
|
||||||
|
vars.heartbeepVar.set('normal')
|
||||||
|
heartbeepOptionMenu = OptionMenu(heartbeepFrame, vars.heartbeepVar, 'double', 'normal', 'half', 'quarter', 'off')
|
||||||
|
heartbeepOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
owPalettesFrame = Frame(romOptionsFrame)
|
||||||
|
owPalettesFrame.grid(row=3, column=0, sticky=E)
|
||||||
|
owPalettesLabel = Label(owPalettesFrame, text='Overworld palettes')
|
||||||
|
owPalettesLabel.pack(side=LEFT)
|
||||||
|
vars.owPalettesVar = StringVar()
|
||||||
|
vars.owPalettesVar.set('default')
|
||||||
|
owPalettesOptionMenu = OptionMenu(owPalettesFrame, vars.owPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
||||||
|
owPalettesOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
uwPalettesFrame = Frame(romOptionsFrame)
|
||||||
|
uwPalettesFrame.grid(row=3, column=1, sticky=E)
|
||||||
|
uwPalettesLabel = Label(uwPalettesFrame, text='Dungeon palettes')
|
||||||
|
uwPalettesLabel.pack(side=LEFT)
|
||||||
|
vars.uwPalettesVar = StringVar()
|
||||||
|
vars.uwPalettesVar.set('default')
|
||||||
|
uwPalettesOptionMenu = OptionMenu(uwPalettesFrame, vars.uwPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
||||||
|
uwPalettesOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
hudPalettesFrame = Frame(romOptionsFrame)
|
||||||
|
hudPalettesFrame.grid(row=4, column=0, sticky=E)
|
||||||
|
hudPalettesLabel = Label(hudPalettesFrame, text='HUD palettes')
|
||||||
|
hudPalettesLabel.pack(side=LEFT)
|
||||||
|
vars.hudPalettesVar = StringVar()
|
||||||
|
vars.hudPalettesVar.set('default')
|
||||||
|
hudPalettesOptionMenu = OptionMenu(hudPalettesFrame, vars.hudPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
||||||
|
hudPalettesOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
swordPalettesFrame = Frame(romOptionsFrame)
|
||||||
|
swordPalettesFrame.grid(row=4, column=1, sticky=E)
|
||||||
|
swordPalettesLabel = Label(swordPalettesFrame, text='Sword palettes')
|
||||||
|
swordPalettesLabel.pack(side=LEFT)
|
||||||
|
vars.swordPalettesVar = StringVar()
|
||||||
|
vars.swordPalettesVar.set('default')
|
||||||
|
swordPalettesOptionMenu = OptionMenu(swordPalettesFrame, vars.swordPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
||||||
|
swordPalettesOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
shieldPalettesFrame = Frame(romOptionsFrame)
|
||||||
|
shieldPalettesFrame.grid(row=5, column=0, sticky=E)
|
||||||
|
shieldPalettesLabel = Label(shieldPalettesFrame, text='Shield palettes')
|
||||||
|
shieldPalettesLabel.pack(side=LEFT)
|
||||||
|
vars.shieldPalettesVar = StringVar()
|
||||||
|
vars.shieldPalettesVar.set('default')
|
||||||
|
shieldPalettesOptionMenu = OptionMenu(shieldPalettesFrame, vars.shieldPalettesVar, 'default', 'random', 'blackout', 'grayscale', 'negative', 'classic', 'dizzy', 'sick', 'puke')
|
||||||
|
shieldPalettesOptionMenu.pack(side=LEFT)
|
||||||
|
|
||||||
|
return romOptionsFrame, vars, set_sprite
|
||||||
|
|
||||||
|
|
||||||
class SpriteSelector():
|
class SpriteSelector():
|
||||||
def __init__(self, parent, callback, adjuster=False):
|
def __init__(self, parent, callback, adjuster=False):
|
||||||
if is_bundled():
|
|
||||||
self.deploy_icons()
|
self.deploy_icons()
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.window = Toplevel(parent)
|
self.window = Toplevel(parent)
|
||||||
|
|
|
@ -25,7 +25,7 @@ class BackgroundTask(object):
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
#safe to call from worker
|
# safe to call from worker
|
||||||
def queue_event(self, event):
|
def queue_event(self, event):
|
||||||
self.queue.put(event)
|
self.queue.put(event)
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ def create_inverted_regions(world, player):
|
||||||
create_cave_region(player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'),
|
create_cave_region(player, 'Dark Lake Hylia Ledge Spike Cave', 'a spiky hint'),
|
||||||
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
|
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',
|
||||||
'Hype Cave - Bottom', 'Hype Cave - Generous Guy']),
|
'Hype Cave - Bottom', 'Hype Cave - Generous Guy']),
|
||||||
create_dw_region(player, 'West Dark World', ['Frog'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Bumper Cave Entrance Rock',
|
create_dw_region(player, 'West Dark World', ['Frog', 'Flute Activation Spot'], ['Village of Outcasts Drop', 'East Dark World River Pier', 'Brewery', 'C-Shaped House', 'Chest Game', 'Thieves Town', 'Bumper Cave Entrance Rock',
|
||||||
'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop',
|
'Skull Woods Forest', 'Village of Outcasts Pegs', 'Village of Outcasts Eastern Rocks', 'Red Shield Shop', 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Dark World Lumberjack Shop',
|
||||||
'West Dark World Teleporter', 'WDW Flute']),
|
'West Dark World Teleporter', 'WDW Flute']),
|
||||||
create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Dark Grassy Lawn Flute']),
|
create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Dark Grassy Lawn Flute']),
|
||||||
|
|
170
ItemPool.py
170
ItemPool.py
|
@ -2,12 +2,12 @@ from collections import namedtuple
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from BaseClasses import Region, RegionType, Location
|
from BaseClasses import Region, RegionType, Location
|
||||||
from Shops import ShopType, Shop, TakeAny, total_shop_slots
|
from Shops import TakeAny, total_shop_slots, set_up_shops, shuffle_shops
|
||||||
from Bosses import place_bosses
|
from Bosses import place_bosses
|
||||||
from Dungeons import get_dungeon_item_pool
|
from Dungeons import get_dungeon_item_pool
|
||||||
from EntranceShuffle import connect_entrance
|
from EntranceShuffle import connect_entrance
|
||||||
from Fill import FillError, fill_restrictive
|
from Fill import FillError, fill_restrictive
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory, GetBeemizerItem
|
||||||
from Rules import forbid_items_for_player
|
from Rules import forbid_items_for_player
|
||||||
|
|
||||||
# This file sets the item pools for various modes. Timed modes and triforce hunt are enforced first, and then extra items are specified per mode to fill in the remaining space.
|
# This file sets the item pools for various modes. Timed modes and triforce hunt are enforced first, and then extra items are specified per mode to fill in the remaining space.
|
||||||
|
@ -297,24 +297,22 @@ def generate_itempool(world, player: int):
|
||||||
|
|
||||||
world.get_location('Ganon', player).event = True
|
world.get_location('Ganon', player).event = True
|
||||||
world.get_location('Ganon', player).locked = True
|
world.get_location('Ganon', player).locked = True
|
||||||
world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False)
|
event_pairs = [
|
||||||
world.get_location('Agahnim 1', player).event = True
|
('Agahnim 1', 'Beat Agahnim 1'),
|
||||||
world.get_location('Agahnim 1', player).locked = True
|
('Agahnim 2', 'Beat Agahnim 2'),
|
||||||
world.push_item(world.get_location('Agahnim 2', player), ItemFactory('Beat Agahnim 2', player), False)
|
('Dark Blacksmith Ruins', 'Pick Up Purple Chest'),
|
||||||
world.get_location('Agahnim 2', player).event = True
|
('Frog', 'Get Frog'),
|
||||||
world.get_location('Agahnim 2', player).locked = True
|
('Missing Smith', 'Return Smith'),
|
||||||
world.push_item(world.get_location('Dark Blacksmith Ruins', player), ItemFactory('Pick Up Purple Chest', player), False)
|
('Floodgate', 'Open Floodgate'),
|
||||||
world.get_location('Dark Blacksmith Ruins', player).event = True
|
('Agahnim 1', 'Beat Agahnim 1'),
|
||||||
world.get_location('Dark Blacksmith Ruins', player).locked = True
|
('Flute Activation Spot', 'Activated Flute')
|
||||||
world.push_item(world.get_location('Frog', player), ItemFactory('Get Frog', player), False)
|
]
|
||||||
world.get_location('Frog', player).event = True
|
for location_name, event_name in event_pairs:
|
||||||
world.get_location('Frog', player).locked = True
|
location = world.get_location(location_name, player)
|
||||||
world.push_item(world.get_location('Missing Smith', player), ItemFactory('Return Smith', player), False)
|
event = ItemFactory(event_name, player)
|
||||||
world.get_location('Missing Smith', player).event = True
|
world.push_item(location, event, False)
|
||||||
world.get_location('Missing Smith', player).locked = True
|
location.event = location.locked = True
|
||||||
world.push_item(world.get_location('Floodgate', player), ItemFactory('Open Floodgate', player), False)
|
|
||||||
world.get_location('Floodgate', player).event = True
|
|
||||||
world.get_location('Floodgate', player).locked = True
|
|
||||||
|
|
||||||
# set up item pool
|
# set up item pool
|
||||||
additional_triforce_pieces = 0
|
additional_triforce_pieces = 0
|
||||||
|
@ -375,7 +373,7 @@ def generate_itempool(world, player: int):
|
||||||
|
|
||||||
if world.goal[player] == 'icerodhunt':
|
if world.goal[player] == 'icerodhunt':
|
||||||
for item in dungeon_items:
|
for item in dungeon_items:
|
||||||
world.itempool.append(ItemFactory('Nothing', player))
|
world.itempool.append(ItemFactory(GetBeemizerItem(world, player, 'Nothing'), player))
|
||||||
world.push_precollected(item)
|
world.push_precollected(item)
|
||||||
else:
|
else:
|
||||||
world.itempool.extend([item for item in dungeon_items])
|
world.itempool.extend([item for item in dungeon_items])
|
||||||
|
@ -390,27 +388,14 @@ def generate_itempool(world, player: int):
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
next(adv_heart_pieces).advancement = True
|
next(adv_heart_pieces).advancement = True
|
||||||
|
|
||||||
beeweights = {0: {None: 100},
|
|
||||||
1: {None: 75, 'trap': 25},
|
|
||||||
2: {None: 40, 'trap': 40, 'bee': 20},
|
|
||||||
3: {'trap': 50, 'bee': 50},
|
|
||||||
4: {'trap': 100}}
|
|
||||||
|
|
||||||
def beemizer(item):
|
|
||||||
if world.beemizer[item.player] and not item.advancement and not item.priority and not item.type:
|
|
||||||
choice = world.random.choices(list(beeweights[world.beemizer[item.player]].keys()),
|
|
||||||
weights=list(beeweights[world.beemizer[item.player]].values()))[0]
|
|
||||||
return item if not choice else ItemFactory("Bee Trap", player) if choice == 'trap' else ItemFactory("Bee",
|
|
||||||
player)
|
|
||||||
return item
|
|
||||||
|
|
||||||
progressionitems = []
|
progressionitems = []
|
||||||
nonprogressionitems = []
|
nonprogressionitems = []
|
||||||
for item in items:
|
for item in items:
|
||||||
if item.advancement or item.priority or item.type:
|
if item.advancement or item.type:
|
||||||
progressionitems.append(item)
|
progressionitems.append(item)
|
||||||
else:
|
else:
|
||||||
nonprogressionitems.append(beemizer(item))
|
nonprogressionitems.append(GetBeemizerItem(world, item.player, item))
|
||||||
world.random.shuffle(nonprogressionitems)
|
world.random.shuffle(nonprogressionitems)
|
||||||
|
|
||||||
if additional_triforce_pieces:
|
if additional_triforce_pieces:
|
||||||
|
@ -427,10 +412,10 @@ def generate_itempool(world, player: int):
|
||||||
mm_medallion = world.random.choice(['Ether', 'Quake', 'Bombos'])
|
mm_medallion = world.random.choice(['Ether', 'Quake', 'Bombos'])
|
||||||
else:
|
else:
|
||||||
mm_medallion = world.required_medallions[player][0]
|
mm_medallion = world.required_medallions[player][0]
|
||||||
if world.required_medallions[player][0] == "random":
|
if world.required_medallions[player][1] == "random":
|
||||||
tr_medallion = world.random.choice(['Ether', 'Quake', 'Bombos'])
|
tr_medallion = world.random.choice(['Ether', 'Quake', 'Bombos'])
|
||||||
else:
|
else:
|
||||||
tr_medallion = world.required_medallions[player][0]
|
tr_medallion = world.required_medallions[player][1]
|
||||||
world.required_medallions[player] = (mm_medallion, tr_medallion)
|
world.required_medallions[player] = (mm_medallion, tr_medallion)
|
||||||
|
|
||||||
place_bosses(world, player)
|
place_bosses(world, player)
|
||||||
|
@ -446,89 +431,6 @@ def generate_itempool(world, player: int):
|
||||||
set_up_take_anys(world, player) # depends on world.itempool to be set
|
set_up_take_anys(world, player) # depends on world.itempool to be set
|
||||||
|
|
||||||
|
|
||||||
def shuffle_shops(world, items, player: int):
|
|
||||||
option = world.shop_shuffle[player]
|
|
||||||
if 'u' in option:
|
|
||||||
progressive = world.progressive[player]
|
|
||||||
progressive = world.random.choice([True, False]) if progressive == 'random' else progressive == 'on'
|
|
||||||
progressive &= world.goal == 'icerodhunt'
|
|
||||||
new_items = ["Bomb Upgrade (+5)"] * 6
|
|
||||||
new_items.append("Bomb Upgrade (+5)" if progressive else "Bomb Upgrade (+10)")
|
|
||||||
|
|
||||||
if not world.retro[player]:
|
|
||||||
new_items += ["Arrow Upgrade (+5)"] * 6
|
|
||||||
new_items.append("Arrow Upgrade (+5)" if progressive else "Arrow Upgrade (+10)")
|
|
||||||
|
|
||||||
world.random.shuffle(new_items) # Decide what gets tossed randomly if it can't insert everything.
|
|
||||||
|
|
||||||
capacityshop: Shop = None
|
|
||||||
for shop in world.shops:
|
|
||||||
if shop.type == ShopType.UpgradeShop and shop.region.player == player and \
|
|
||||||
shop.region.name == "Capacity Upgrade":
|
|
||||||
shop.clear_inventory()
|
|
||||||
capacityshop = shop
|
|
||||||
|
|
||||||
if world.goal[player] != 'icerodhunt':
|
|
||||||
for i, item in enumerate(items):
|
|
||||||
if "Heart" not in item.name:
|
|
||||||
items[i] = ItemFactory(new_items.pop(), player)
|
|
||||||
if not new_items:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
logging.warning(f"Not all upgrades put into Player{player}' item pool. Putting remaining items in Capacity Upgrade shop instead.")
|
|
||||||
bombupgrades = sum(1 for item in new_items if 'Bomb Upgrade' in item)
|
|
||||||
arrowupgrades = sum(1 for item in new_items if 'Arrow Upgrade' in item)
|
|
||||||
if bombupgrades:
|
|
||||||
capacityshop.add_inventory(1, 'Bomb Upgrade (+5)', 100, bombupgrades)
|
|
||||||
if arrowupgrades:
|
|
||||||
capacityshop.add_inventory(1, 'Arrow Upgrade (+5)', 100, arrowupgrades)
|
|
||||||
else:
|
|
||||||
for item in new_items:
|
|
||||||
world.push_precollected(ItemFactory(item, player))
|
|
||||||
|
|
||||||
if 'p' in option or 'i' in option:
|
|
||||||
shops = []
|
|
||||||
upgrade_shops = []
|
|
||||||
total_inventory = []
|
|
||||||
for shop in world.shops:
|
|
||||||
if shop.region.player == player:
|
|
||||||
if shop.type == ShopType.UpgradeShop:
|
|
||||||
upgrade_shops.append(shop)
|
|
||||||
elif shop.type == ShopType.Shop:
|
|
||||||
if shop.region.name == 'Potion Shop' and not 'w' in option:
|
|
||||||
# don't modify potion shop
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
shops.append(shop)
|
|
||||||
total_inventory.extend(shop.inventory)
|
|
||||||
|
|
||||||
if 'p' in option:
|
|
||||||
def price_adjust(price: int) -> int:
|
|
||||||
# it is important that a base price of 0 always returns 0 as new price!
|
|
||||||
adjust = 2 if price < 100 else 5
|
|
||||||
return int((price / adjust) * (0.5 + world.random.random() * 1.5)) * adjust
|
|
||||||
|
|
||||||
def adjust_item(item):
|
|
||||||
if item:
|
|
||||||
item["price"] = price_adjust(item["price"])
|
|
||||||
item['replacement_price'] = price_adjust(item["price"])
|
|
||||||
|
|
||||||
for item in total_inventory:
|
|
||||||
adjust_item(item)
|
|
||||||
for shop in upgrade_shops:
|
|
||||||
for item in shop.inventory:
|
|
||||||
adjust_item(item)
|
|
||||||
|
|
||||||
if 'i' in option:
|
|
||||||
world.random.shuffle(total_inventory)
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
for shop in shops:
|
|
||||||
slots = shop.slots
|
|
||||||
shop.inventory = total_inventory[i:i + slots]
|
|
||||||
i += slots
|
|
||||||
|
|
||||||
|
|
||||||
take_any_locations = {
|
take_any_locations = {
|
||||||
'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Light World Bomb Hut',
|
'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Light World Bomb Hut',
|
||||||
'Fortune Teller (Light)', 'Lake Hylia Fortune Teller', 'Lumberjack House', 'Bonk Fairy (Light)',
|
'Fortune Teller (Light)', 'Lake Hylia Fortune Teller', 'Lumberjack House', 'Bonk Fairy (Light)',
|
||||||
|
@ -639,32 +541,6 @@ def fill_prizes(world, attempts=15):
|
||||||
raise FillError('Unable to place dungeon prizes')
|
raise FillError('Unable to place dungeon prizes')
|
||||||
|
|
||||||
|
|
||||||
def set_up_shops(world, player: int):
|
|
||||||
# TODO: move hard+ mode changes for shields here, utilizing the new shops
|
|
||||||
|
|
||||||
if world.retro[player]:
|
|
||||||
rss = world.get_region('Red Shield Shop', player).shop
|
|
||||||
replacement_items = [['Red Potion', 150], ['Green Potion', 75], ['Blue Potion', 200], ['Bombs (10)', 50],
|
|
||||||
['Blue Shield', 50], ['Small Heart', 10]] # Can't just replace the single arrow with 10 arrows as retro doesn't need them.
|
|
||||||
if world.keyshuffle[player] == "universal":
|
|
||||||
replacement_items.append(['Small Key (Universal)', 100])
|
|
||||||
replacement_item = world.random.choice(replacement_items)
|
|
||||||
rss.add_inventory(2, 'Single Arrow', 80, 1, replacement_item[0], replacement_item[1])
|
|
||||||
rss.locked = True
|
|
||||||
|
|
||||||
if world.keyshuffle[player] == "universal" or world.retro[player]:
|
|
||||||
for shop in world.random.sample([s for s in world.shops if
|
|
||||||
s.custom and not s.locked and s.type == ShopType.Shop and s.region.player == player],
|
|
||||||
5):
|
|
||||||
shop.locked = True
|
|
||||||
slots = [0, 0, 1, 1, 2, 2]
|
|
||||||
world.random.shuffle(slots)
|
|
||||||
slots = iter(slots)
|
|
||||||
if world.keyshuffle[player] == "universal":
|
|
||||||
shop.add_inventory(next(slots), 'Small Key (Universal)', 100)
|
|
||||||
if world.retro[player]:
|
|
||||||
shop.push_inventory(next(slots), 'Single Arrow', 80)
|
|
||||||
|
|
||||||
def get_pool_core(world, player: int):
|
def get_pool_core(world, player: int):
|
||||||
progressive = world.progressive[player]
|
progressive = world.progressive[player]
|
||||||
shuffle = world.shuffle[player]
|
shuffle = world.shuffle[player]
|
||||||
|
|
352
Items.py
352
Items.py
|
@ -1,6 +1,19 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
def GetBeemizerItem(world, player, item):
|
||||||
|
item_name = item if isinstance(item, str) else item.name
|
||||||
|
if world.beemizer[player] and item_name in trap_replaceable:
|
||||||
|
if world.random.random() < world.beemizer[player] * 0.25:
|
||||||
|
if world.random.random() < (0.5 + world.beemizer[player] * 0.1):
|
||||||
|
return "Bee Trap" if isinstance(item, str) else ItemFactory("Bee Trap", player)
|
||||||
|
else:
|
||||||
|
return "Bee" if isinstance(item, str) else ItemFactory("Bee", player)
|
||||||
|
else:
|
||||||
|
return item
|
||||||
|
else:
|
||||||
|
return item
|
||||||
|
|
||||||
|
|
||||||
def ItemFactory(items, player):
|
def ItemFactory(items, player):
|
||||||
from BaseClasses import Item
|
from BaseClasses import Item
|
||||||
|
@ -11,184 +24,183 @@ def ItemFactory(items, player):
|
||||||
singleton = True
|
singleton = True
|
||||||
for item in items:
|
for item in items:
|
||||||
if item in item_table:
|
if item in item_table:
|
||||||
advancement, priority, type, code, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text = item_table[item]
|
ret.append(Item(item, *item_table[item], player))
|
||||||
ret.append(Item(item, advancement, priority, type, code, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text, player))
|
|
||||||
else:
|
else:
|
||||||
logging.getLogger('').warning('Unknown Item: %s', item)
|
raise Exception(f"Unknown item {item}")
|
||||||
return None
|
|
||||||
|
|
||||||
if singleton:
|
if singleton:
|
||||||
return ret[0]
|
return ret[0]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
# Format: Name: (Advancement, Priority, Type, ItemCode, Pedestal Hint Text, Pedestal Credit Text, Sick Kid Credit Text, Zora Credit Text, Witch Credit Text, Flute Boy Credit Text, Hint Text)
|
# Format: Name: (Advancement, Type, ItemCode, Pedestal Hint Text, Pedestal Credit Text, Sick Kid Credit Text, Zora Credit Text, Witch Credit Text, Flute Boy Credit Text, Hint Text)
|
||||||
item_table = {'Bow': (True, False, None, 0x0B, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'the Bow'),
|
item_table = {'Bow': (True, None, 0x0B, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'the Bow'),
|
||||||
'Progressive Bow': (True, False, None, 0x64, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'),
|
'Progressive Bow': (True, None, 0x64, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'),
|
||||||
'Progressive Bow (Alt)': (True, False, None, 0x65, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'),
|
'Progressive Bow (Alt)': (True, None, 0x65, 'You have\nchosen the\narcher class.', 'the stick and twine', 'arrow-slinging kid', 'arrow sling for sale', 'witch and robin hood', 'archer boy shoots again', 'a Bow'),
|
||||||
'Silver Arrows': (True, False, None, 0x58, 'Do you fancy\nsilver tipped\narrows?', 'and the ganonsbane','ganon-killing kid', 'ganon doom for sale', 'fungus for pork','archer boy shines again', 'the Silver Arrows'),
|
'Silver Arrows': (True, None, 0x58, 'Do you fancy\nsilver tipped\narrows?', 'and the ganonsbane','ganon-killing kid', 'ganon doom for sale', 'fungus for pork','archer boy shines again', 'the Silver Arrows'),
|
||||||
'Silver Bow': (True, False, None, 0x3B, 'Buy 1 Silver\nget Archery\nfor free.', 'the baconmaker', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'the Silver Bow'),
|
'Silver Bow': (True, None, 0x3B, 'Buy 1 Silver\nget Archery\nfor free.', 'the baconmaker', 'ganon-killing kid', 'ganon doom for sale', 'fungus for pork', 'archer boy shines again', 'the Silver Bow'),
|
||||||
'Book of Mudora': (True, False, None, 0x1D, 'Hylian\nfor\nDingusses.', 'and the story book', 'the scholarly kid', 'moon runes for sale', 'drugs for literacy', 'book-worm boy can read again', 'the Book'),
|
'Book of Mudora': (True, None, 0x1D, 'Hylian\nfor\nDingusses.', 'and the story book', 'the scholarly kid', 'moon runes for sale', 'drugs for literacy', 'book-worm boy can read again', 'the Book'),
|
||||||
'Hammer': (True, False, None, 0x09, 'stop\nhammer time!', 'and m c hammer', 'hammer-smashing kid', 'm c hammer for sale', 'stop... hammer time', 'stop, hammer time', 'the Hammer'),
|
'Hammer': (True, None, 0x09, 'stop\nhammer time!', 'and m c hammer', 'hammer-smashing kid', 'm c hammer for sale', 'stop... hammer time', 'stop, hammer time', 'the Hammer'),
|
||||||
'Hookshot': (True, False, None, 0x0A, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'),
|
'Hookshot': (True, None, 0x0A, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'),
|
||||||
'Magic Mirror': (True, False, None, 0x1A, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'),
|
'Magic Mirror': (True, None, 0x1A, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the Mirror'),
|
||||||
'Flute': (True, False, None, 0x14, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'flute boy plays again', 'the Flute'),
|
'Flute': (True, None, 0x14, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'flute boy plays again', 'the Flute'),
|
||||||
'Pegasus Boots': (True, False, None, 0x4B, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'),
|
'Pegasus Boots': (True, None, 0x4B, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the Boots'),
|
||||||
'Power Glove': (True, False, None, 0x1B, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the Glove'),
|
'Power Glove': (True, None, 0x1B, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the Glove'),
|
||||||
'Cape': (True, False, None, 0x19, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the Cape'),
|
'Cape': (True, None, 0x19, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the Cape'),
|
||||||
'Mushroom': (True, False, None, 0x29, 'I\'m a fun guy!\n\nI\'m a funghi!', 'and the legal drugs', 'the drug-dealing kid', 'legal drugs for sale', 'shroom swap', 'shroom boy sells drugs again', 'the Mushroom'),
|
'Mushroom': (True, None, 0x29, 'I\'m a fun guy!\n\nI\'m a funghi!', 'and the legal drugs', 'the drug-dealing kid', 'legal drugs for sale', 'shroom swap', 'shroom boy sells drugs again', 'the Mushroom'),
|
||||||
'Shovel': (True, False, None, 0x13, 'Can\n You\n Dig it?', 'and the spade', 'archaeologist kid', 'dirt spade for sale', 'can you dig it', 'shovel boy digs again', 'the Shovel'),
|
'Shovel': (True, None, 0x13, 'Can\n You\n Dig it?', 'and the spade', 'archaeologist kid', 'dirt spade for sale', 'can you dig it', 'shovel boy digs again', 'the Shovel'),
|
||||||
'Lamp': (True, False, None, 0x12, 'Baby, baby,\nbaby.\nLight my way!', 'and the flashlight', 'light-shining kid', 'flashlight for sale', 'fungus for illumination', 'illuminated boy can see again', 'the Lamp'),
|
'Lamp': (True, None, 0x12, 'Baby, baby,\nbaby.\nLight my way!', 'and the flashlight', 'light-shining kid', 'flashlight for sale', 'fungus for illumination', 'illuminated boy can see again', 'the Lamp'),
|
||||||
'Magic Powder': (True, False, None, 0x0D, 'you can turn\nanti-faeries\ninto faeries', 'and the magic sack', 'the sack-holding kid', 'magic sack for sale', 'the witch and assistant', 'magic boy plays marbles again', 'the Powder'),
|
'Magic Powder': (True, None, 0x0D, 'you can turn\nanti-faeries\ninto faeries', 'and the magic sack', 'the sack-holding kid', 'magic sack for sale', 'the witch and assistant', 'magic boy plays marbles again', 'the Powder'),
|
||||||
'Moon Pearl': (True, False, None, 0x1F, ' Bunny Link\n be\n gone!', 'and the jaw breaker', 'fortune-telling kid', 'lunar orb for sale', 'shrooms for moon rock', 'moon boy plays ball again', 'the Moon Pearl'),
|
'Moon Pearl': (True, None, 0x1F, ' Bunny Link\n be\n gone!', 'and the jaw breaker', 'fortune-telling kid', 'lunar orb for sale', 'shrooms for moon rock', 'moon boy plays ball again', 'the Moon Pearl'),
|
||||||
'Cane of Somaria': (True, False, None, 0x15, 'I make blocks\nto hold down\nswitches!', 'and the red blocks', 'the block-making kid', 'block stick for sale', 'block stick for trade', 'cane boy makes blocks again', 'the Red Cane'),
|
'Cane of Somaria': (True, None, 0x15, 'I make blocks\nto hold down\nswitches!', 'and the red blocks', 'the block-making kid', 'block stick for sale', 'block stick for trade', 'cane boy makes blocks again', 'the Red Cane'),
|
||||||
'Fire Rod': (True, False, None, 0x07, 'I\'m the hot\nrod. I make\nthings burn!', 'and the flamethrower', 'fire-starting kid', 'rage rod for sale', 'fungus for rage-rod', 'firestarter boy burns again', 'the Fire Rod'),
|
'Fire Rod': (True, None, 0x07, 'I\'m the hot\nrod. I make\nthings burn!', 'and the flamethrower', 'fire-starting kid', 'rage rod for sale', 'fungus for rage-rod', 'firestarter boy burns again', 'the Fire Rod'),
|
||||||
'Flippers': (True, False, None, 0x1E, 'fancy a swim?', 'and the toewebs', 'the swimming kid', 'finger webs for sale', 'shrooms let you swim', 'swimming boy swims again', 'the Flippers'),
|
'Flippers': (True, None, 0x1E, 'fancy a swim?', 'and the toewebs', 'the swimming kid', 'finger webs for sale', 'shrooms let you swim', 'swimming boy swims again', 'the Flippers'),
|
||||||
'Ice Rod': (True, False, None, 0x08, 'I\'m the cold\nrod. I make\nthings freeze!', 'and the freeze ray', 'the ice-bending kid', 'freeze ray for sale', 'fungus for ice-rod', 'ice-cube boy freezes again', 'the Ice Rod'),
|
'Ice Rod': (True, None, 0x08, 'I\'m the cold\nrod. I make\nthings freeze!', 'and the freeze ray', 'the ice-bending kid', 'freeze ray for sale', 'fungus for ice-rod', 'ice-cube boy freezes again', 'the Ice Rod'),
|
||||||
'Titans Mitts': (True, False, None, 0x1C, 'Now you can\nlift heavy\nstuff!', 'and the golden glove', 'body-building kid', 'carry glove for sale', 'fungus for bling-gloves', 'body-building boy has gold again', 'the Mitts'),
|
'Titans Mitts': (True, None, 0x1C, 'Now you can\nlift heavy\nstuff!', 'and the golden glove', 'body-building kid', 'carry glove for sale', 'fungus for bling-gloves', 'body-building boy has gold again', 'the Mitts'),
|
||||||
'Bombos': (True, False, None, 0x0F, 'Burn, baby,\nburn! Fear my\nring of fire!', 'and the swirly coin', 'coin-collecting kid', 'swirly coin for sale', 'shrooms for swirly-coin', 'medallion boy melts room again', 'Bombos'),
|
'Bombos': (True, None, 0x0F, 'Burn, baby,\nburn! Fear my\nring of fire!', 'and the swirly coin', 'coin-collecting kid', 'swirly coin for sale', 'shrooms for swirly-coin', 'medallion boy melts room again', 'Bombos'),
|
||||||
'Ether': (True, False, None, 0x10, 'This magic\ncoin freezes\neverything!', 'and the bolt coin', 'coin-collecting kid', 'bolt coin for sale', 'shrooms for bolt-coin', 'medallion boy sees floor again', 'Ether'),
|
'Ether': (True, None, 0x10, 'This magic\ncoin freezes\neverything!', 'and the bolt coin', 'coin-collecting kid', 'bolt coin for sale', 'shrooms for bolt-coin', 'medallion boy sees floor again', 'Ether'),
|
||||||
'Quake': (True, False, None, 0x11, 'Maxing out the\nRichter scale\nis what I do!', 'and the wavy coin', 'coin-collecting kid', 'wavy coin for sale', 'shrooms for wavy-coin', 'medallion boy shakes dirt again', 'Quake'),
|
'Quake': (True, None, 0x11, 'Maxing out the\nRichter scale\nis what I do!', 'and the wavy coin', 'coin-collecting kid', 'wavy coin for sale', 'shrooms for wavy-coin', 'medallion boy shakes dirt again', 'Quake'),
|
||||||
'Bottle': (True, False, None, 0x16, 'Now you can\nstore potions\nand stuff!', 'and the terrarium', 'the terrarium kid', 'terrarium for sale', 'special promotion', 'bottle boy has terrarium again', 'a bottle'),
|
'Bottle': (True, None, 0x16, 'Now you can\nstore potions\nand stuff!', 'and the terrarium', 'the terrarium kid', 'terrarium for sale', 'special promotion', 'bottle boy has terrarium again', 'a bottle'),
|
||||||
'Bottle (Red Potion)': (True, False, None, 0x2B, 'Hearty red goop!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'a bottle'),
|
'Bottle (Red Potion)': (True, None, 0x2B, 'Hearty red goop!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'a bottle'),
|
||||||
'Bottle (Green Potion)': (True, False, None, 0x2C, 'Refreshing green goop!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a bottle'),
|
'Bottle (Green Potion)': (True, None, 0x2C, 'Refreshing green goop!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a bottle'),
|
||||||
'Bottle (Blue Potion)': (True, False, None, 0x2D, 'Delicious blue goop!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a bottle'),
|
'Bottle (Blue Potion)': (True, None, 0x2D, 'Delicious blue goop!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a bottle'),
|
||||||
'Bottle (Fairy)': (True, False, None, 0x3D, 'Save me and I will revive you', 'and the captive', 'the tingle kid','hostage for sale', 'fairy dust and shrooms', 'bottle boy has friend again', 'a bottle'),
|
'Bottle (Fairy)': (True, None, 0x3D, 'Save me and I will revive you', 'and the captive', 'the tingle kid','hostage for sale', 'fairy dust and shrooms', 'bottle boy has friend again', 'a bottle'),
|
||||||
'Bottle (Bee)': (True, False, None, 0x3C, 'I will sting your foes a few times', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bottle'),
|
'Bottle (Bee)': (True, None, 0x3C, 'I will sting your foes a few times', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bottle'),
|
||||||
'Bottle (Good Bee)': (True, False, None, 0x48, 'I will sting your foes a whole lot!', 'and the sparkle sting', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has beetor again', 'a bottle'),
|
'Bottle (Good Bee)': (True, None, 0x48, 'I will sting your foes a whole lot!', 'and the sparkle sting', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has beetor again', 'a bottle'),
|
||||||
'Master Sword': (True, False, 'Sword', 0x50, 'I beat barries and pigs alike', 'and the master sword', 'sword-wielding kid', 'glow sword for sale', 'fungus for blue slasher', 'sword boy fights again', 'the Master Sword'),
|
'Master Sword': (True, 'Sword', 0x50, 'I beat barries and pigs alike', 'and the master sword', 'sword-wielding kid', 'glow sword for sale', 'fungus for blue slasher', 'sword boy fights again', 'the Master Sword'),
|
||||||
'Tempered Sword': (True, False, 'Sword', 0x02, 'I stole the\nblacksmith\'s\njob!', 'the tempered sword', 'sword-wielding kid', 'flame sword for sale', 'fungus for red slasher', 'sword boy fights again', 'the Tempered Sword'),
|
'Tempered Sword': (True, 'Sword', 0x02, 'I stole the\nblacksmith\'s\njob!', 'the tempered sword', 'sword-wielding kid', 'flame sword for sale', 'fungus for red slasher', 'sword boy fights again', 'the Tempered Sword'),
|
||||||
'Fighter Sword': (True, False, 'Sword', 0x49, 'A pathetic\nsword rests\nhere!', 'the tiny sword', 'sword-wielding kid', 'tiny sword for sale', 'fungus for tiny slasher', 'sword boy fights again', 'the Small Sword'),
|
'Fighter Sword': (True, 'Sword', 0x49, 'A pathetic\nsword rests\nhere!', 'the tiny sword', 'sword-wielding kid', 'tiny sword for sale', 'fungus for tiny slasher', 'sword boy fights again', 'the Small Sword'),
|
||||||
'Golden Sword': (True, False, 'Sword', 0x03, 'The butter\nsword rests\nhere!', 'and the butter sword', 'sword-wielding kid', 'butter for sale', 'cap churned to butter', 'sword boy fights again', 'the Golden Sword'),
|
'Golden Sword': (True, 'Sword', 0x03, 'The butter\nsword rests\nhere!', 'and the butter sword', 'sword-wielding kid', 'butter for sale', 'cap churned to butter', 'sword boy fights again', 'the Golden Sword'),
|
||||||
'Progressive Sword': (True, False, 'Sword', 0x5E, 'a better copy\nof your sword\nfor your time', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'a Sword'),
|
'Progressive Sword': (True, 'Sword', 0x5E, 'a better copy\nof your sword\nfor your time', 'the unknown sword', 'sword-wielding kid', 'sword for sale', 'fungus for some slasher', 'sword boy fights again', 'a Sword'),
|
||||||
'Progressive Glove': (True, False, None, 0x61, 'a way to lift\nheavier things', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'a Glove'),
|
'Progressive Glove': (True, None, 0x61, 'a way to lift\nheavier things', 'and the lift upgrade', 'body-building kid', 'some glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'a Glove'),
|
||||||
'Green Pendant': (True, False, 'Crystal', (0x04, 0x38, 0x62, 0x00, 0x69, 0x01), None, None, None, None, None, None, None),
|
'Green Pendant': (True, 'Crystal', (0x04, 0x38, 0x62, 0x00, 0x69, 0x01), None, None, None, None, None, None, None),
|
||||||
'Blue Pendant': (True, False, 'Crystal', (0x02, 0x34, 0x60, 0x00, 0x69, 0x02), None, None, None, None, None, None, None),
|
'Blue Pendant': (True, 'Crystal', (0x02, 0x34, 0x60, 0x00, 0x69, 0x02), None, None, None, None, None, None, None),
|
||||||
'Red Pendant': (True, False, 'Crystal', (0x01, 0x32, 0x60, 0x00, 0x69, 0x03), None, None, None, None, None, None, None),
|
'Red Pendant': (True, 'Crystal', (0x01, 0x32, 0x60, 0x00, 0x69, 0x03), None, None, None, None, None, None, None),
|
||||||
'Triforce': (True, False, None, 0x6A, '\n YOU WIN!', 'and the triforce', 'victorious kid', 'victory for sale', 'fungus for the win', 'greedy boy wins game again', 'the Triforce'),
|
'Triforce': (True, None, 0x6A, '\n YOU WIN!', 'and the triforce', 'victorious kid', 'victory for sale', 'fungus for the win', 'greedy boy wins game again', 'the Triforce'),
|
||||||
'Power Star': (True, False, None, 0x6B, 'a small victory', 'and the power star', 'star-struck kid', 'star for sale', 'see stars with shroom', 'mario powers up again', 'a Power Star'),
|
'Power Star': (True, None, 0x6B, 'a small victory', 'and the power star', 'star-struck kid', 'star for sale', 'see stars with shroom', 'mario powers up again', 'a Power Star'),
|
||||||
'Triforce Piece': (True, False, None, 0x6C, 'a small victory', 'and the thirdforce', 'triangular kid', 'triangle for sale', 'fungus for triangle', 'wise boy has triangle again', 'a Triforce Piece'),
|
'Triforce Piece': (True, None, 0x6C, 'a small victory', 'and the thirdforce', 'triangular kid', 'triangle for sale', 'fungus for triangle', 'wise boy has triangle again', 'a Triforce Piece'),
|
||||||
'Crystal 1': (True, False, 'Crystal', (0x02, 0x34, 0x64, 0x40, 0x7F, 0x06), None, None, None, None, None, None, None),
|
'Crystal 1': (True, 'Crystal', (0x02, 0x34, 0x64, 0x40, 0x7F, 0x06), None, None, None, None, None, None, None),
|
||||||
'Crystal 2': (True, False, 'Crystal', (0x10, 0x34, 0x64, 0x40, 0x79, 0x06), None, None, None, None, None, None, None),
|
'Crystal 2': (True, 'Crystal', (0x10, 0x34, 0x64, 0x40, 0x79, 0x06), None, None, None, None, None, None, None),
|
||||||
'Crystal 3': (True, False, 'Crystal', (0x40, 0x34, 0x64, 0x40, 0x6C, 0x06), None, None, None, None, None, None, None),
|
'Crystal 3': (True, 'Crystal', (0x40, 0x34, 0x64, 0x40, 0x6C, 0x06), None, None, None, None, None, None, None),
|
||||||
'Crystal 4': (True, False, 'Crystal', (0x20, 0x34, 0x64, 0x40, 0x6D, 0x06), None, None, None, None, None, None, None),
|
'Crystal 4': (True, 'Crystal', (0x20, 0x34, 0x64, 0x40, 0x6D, 0x06), None, None, None, None, None, None, None),
|
||||||
'Crystal 5': (True, False, 'Crystal', (0x04, 0x32, 0x64, 0x40, 0x6E, 0x06), None, None, None, None, None, None, None),
|
'Crystal 5': (True, 'Crystal', (0x04, 0x32, 0x64, 0x40, 0x6E, 0x06), None, None, None, None, None, None, None),
|
||||||
'Crystal 6': (True, False, 'Crystal', (0x01, 0x32, 0x64, 0x40, 0x6F, 0x06), None, None, None, None, None, None, None),
|
'Crystal 6': (True, 'Crystal', (0x01, 0x32, 0x64, 0x40, 0x6F, 0x06), None, None, None, None, None, None, None),
|
||||||
'Crystal 7': (True, False, 'Crystal', (0x08, 0x34, 0x64, 0x40, 0x7C, 0x06), None, None, None, None, None, None, None),
|
'Crystal 7': (True, 'Crystal', (0x08, 0x34, 0x64, 0x40, 0x7C, 0x06), None, None, None, None, None, None, None),
|
||||||
'Single Arrow': (False, False, None, 0x43, 'a lonely arrow\nsits here.', 'and the arrow', 'stick-collecting kid', 'sewing needle for sale', 'fungus for arrow', 'archer boy sews again', 'an arrow'),
|
'Single Arrow': (False, None, 0x43, 'a lonely arrow\nsits here.', 'and the arrow', 'stick-collecting kid', 'sewing needle for sale', 'fungus for arrow', 'archer boy sews again', 'an arrow'),
|
||||||
'Arrows (10)': (False, False, None, 0x44, 'This will give\nyou ten shots\nwith your bow!', 'and the arrow pack','stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again','ten arrows'),
|
'Arrows (10)': (False, None, 0x44, 'This will give\nyou ten shots\nwith your bow!', 'and the arrow pack','stick-collecting kid', 'sewing kit for sale', 'fungus for arrows', 'archer boy sews again','ten arrows'),
|
||||||
'Arrow Upgrade (+10)': (False, False, None, 0x54, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
|
'Arrow Upgrade (+10)': (False, None, 0x54, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
|
||||||
'Arrow Upgrade (+5)': (False, False, None, 0x53, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
|
'Arrow Upgrade (+5)': (False, None, 0x53, 'increase arrow\nstorage, low\nlow price', 'and the quiver', 'quiver-enlarging kid', 'arrow boost for sale', 'witch and more skewers', 'upgrade boy sews more again', 'arrow capacity'),
|
||||||
'Single Bomb': (False, False, None, 0x27, 'I make things\ngo BOOM! But\njust once.', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'a bomb'),
|
'Single Bomb': (False, None, 0x27, 'I make things\ngo BOOM! But\njust once.', 'and the explosion', 'the bomb-holding kid', 'firecracker for sale', 'blend fungus into bomb', '\'splosion boy explodes again', 'a bomb'),
|
||||||
'Bombs (3)': (False, False, None, 0x28, 'I make things\ngo triple\nBOOM!!!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'three bombs'),
|
'Bombs (3)': (False, None, 0x28, 'I make things\ngo triple\nBOOM!!!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'three bombs'),
|
||||||
'Bombs (10)': (False, False, None, 0x31, 'I make things\ngo BOOM! Ten\ntimes!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'ten bombs'),
|
'Bombs (10)': (False, None, 0x31, 'I make things\ngo BOOM! Ten\ntimes!', 'and the explosions', 'the bomb-holding kid', 'firecrackers for sale', 'blend fungus into bombs', '\'splosion boy explodes again', 'ten bombs'),
|
||||||
'Bomb Upgrade (+10)': (False, False, None, 0x52, 'increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
|
'Bomb Upgrade (+10)': (False, None, 0x52, 'increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
|
||||||
'Bomb Upgrade (+5)': (False, False, None, 0x51, 'increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
|
'Bomb Upgrade (+5)': (False, None, 0x51, 'increase bomb\nstorage, low\nlow price', 'and the bomb bag', 'boom-enlarging kid', 'bomb boost for sale', 'the shroom goes boom', 'upgrade boy explodes more again', 'bomb capacity'),
|
||||||
'Blue Mail': (False, True, None, 0x22, 'Now you\'re a\nblue elf!', 'and the banana hat', 'the protected kid', 'banana hat for sale', 'the clothing store', 'tailor boy banana hatted again', 'the Blue Mail'),
|
'Blue Mail': (False, None, 0x22, 'Now you\'re a\nblue elf!', 'and the banana hat', 'the protected kid', 'banana hat for sale', 'the clothing store', 'tailor boy banana hatted again', 'the Blue Mail'),
|
||||||
'Red Mail': (False, True, None, 0x23, 'Now you\'re a\nred elf!', 'and the eggplant hat', 'well-protected kid', 'purple hat for sale', 'the nice clothing store', 'tailor boy fears nothing again', 'the Red Mail'),
|
'Red Mail': (False, None, 0x23, 'Now you\'re a\nred elf!', 'and the eggplant hat', 'well-protected kid', 'purple hat for sale', 'the nice clothing store', 'tailor boy fears nothing again', 'the Red Mail'),
|
||||||
'Progressive Mail': (False, True, None, 0x60, 'time for a\nchange of\nclothes?', 'and the unknown hat', 'the protected kid', 'new hat for sale', 'the clothing store', 'tailor boy has threads again', 'some armor'),
|
'Progressive Mail': (False, None, 0x60, 'time for a\nchange of\nclothes?', 'and the unknown hat', 'the protected kid', 'new hat for sale', 'the clothing store', 'tailor boy has threads again', 'some armor'),
|
||||||
'Blue Boomerang': (True, False, None, 0x0C, 'No matter what\nyou do, blue\nreturns to you', 'and the bluemarang', 'the bat-throwing kid', 'bent stick for sale', 'fungus for puma-stick', 'throwing boy plays fetch again', 'the Blue Boomerang'),
|
'Blue Boomerang': (True, None, 0x0C, 'No matter what\nyou do, blue\nreturns to you', 'and the bluemarang', 'the bat-throwing kid', 'bent stick for sale', 'fungus for puma-stick', 'throwing boy plays fetch again', 'the Blue Boomerang'),
|
||||||
'Red Boomerang': (True, False, None, 0x2A, 'No matter what\nyou do, red\nreturns to you', 'and the badmarang', 'the bat-throwing kid', 'air foil for sale', 'fungus for return-stick', 'magical boy plays fetch again', 'the Red Boomerang'),
|
'Red Boomerang': (True, None, 0x2A, 'No matter what\nyou do, red\nreturns to you', 'and the badmarang', 'the bat-throwing kid', 'air foil for sale', 'fungus for return-stick', 'magical boy plays fetch again', 'the Red Boomerang'),
|
||||||
'Blue Shield': (False, True, None, 0x04, 'Now you can\ndefend against\npebbles!', 'and the stone blocker', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'the Blue Shield'),
|
'Blue Shield': (False, None, 0x04, 'Now you can\ndefend against\npebbles!', 'and the stone blocker', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'the Blue Shield'),
|
||||||
'Red Shield': (False, True, None, 0x05, 'Now you can\ndefend against\nfireballs!', 'and the shot blocker', 'shield-wielding kid', 'fire shield for sale', 'fungus for fire shield', 'shield boy defends again', 'the Red Shield'),
|
'Red Shield': (False, None, 0x05, 'Now you can\ndefend against\nfireballs!', 'and the shot blocker', 'shield-wielding kid', 'fire shield for sale', 'fungus for fire shield', 'shield boy defends again', 'the Red Shield'),
|
||||||
'Mirror Shield': (True, False, None, 0x06, 'Now you can\ndefend against\nlasers!', 'and the laser blocker', 'shield-wielding kid', 'face shield for sale', 'fungus for face shield', 'shield boy defends again', 'the Mirror Shield'),
|
'Mirror Shield': (True, None, 0x06, 'Now you can\ndefend against\nlasers!', 'and the laser blocker', 'shield-wielding kid', 'face shield for sale', 'fungus for face shield', 'shield boy defends again', 'the Mirror Shield'),
|
||||||
'Progressive Shield': (True, False, None, 0x5F, 'have a better\nblocker in\nfront of you', 'and the new shield', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'a shield'),
|
'Progressive Shield': (True, None, 0x5F, 'have a better\nblocker in\nfront of you', 'and the new shield', 'shield-wielding kid', 'shield for sale', 'fungus for shield', 'shield boy defends again', 'a shield'),
|
||||||
'Bug Catching Net': (True, False, None, 0x21, 'Let\'s catch\nsome bees and\nfaeries!', 'and the bee catcher', 'the bug-catching kid', 'stick web for sale', 'fungus for butterflies', 'wrong boy catches bees again', 'the Bug Net'),
|
'Bug Catching Net': (True, None, 0x21, 'Let\'s catch\nsome bees and\nfaeries!', 'and the bee catcher', 'the bug-catching kid', 'stick web for sale', 'fungus for butterflies', 'wrong boy catches bees again', 'the Bug Net'),
|
||||||
'Cane of Byrna': (True, False, None, 0x18, 'Use this to\nbecome\ninvincible!', 'and the bad cane', 'the spark-making kid', 'spark stick for sale', 'spark-stick for trade', 'cane boy encircles again', 'the Blue Cane'),
|
'Cane of Byrna': (True, None, 0x18, 'Use this to\nbecome\ninvincible!', 'and the bad cane', 'the spark-making kid', 'spark stick for sale', 'spark-stick for trade', 'cane boy encircles again', 'the Blue Cane'),
|
||||||
'Boss Heart Container': (False, False, None, 0x3E, 'Maximum health\nincreased!\nYeah!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'),
|
'Boss Heart Container': (False, None, 0x3E, 'Maximum health\nincreased!\nYeah!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'),
|
||||||
'Sanctuary Heart Container': (False, False, None, 0x3F, 'Maximum health\nincreased!\nYeah!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'),
|
'Sanctuary Heart Container': (False, None, 0x3F, 'Maximum health\nincreased!\nYeah!', 'and the full heart', 'the life-giving kid', 'love for sale', 'fungus for life', 'life boy feels love again', 'a heart'),
|
||||||
'Piece of Heart': (False, False, None, 0x17, 'Just a little\npiece of love!', 'and the broken heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart piece'),
|
'Piece of Heart': (False, None, 0x17, 'Just a little\npiece of love!', 'and the broken heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart piece'),
|
||||||
'Rupee (1)': (False, False, None, 0x34, 'Just pocket\nchange. Move\nright along.', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'a green rupee'),
|
'Rupee (1)': (False, None, 0x34, 'Just pocket\nchange. Move\nright along.', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'a green rupee'),
|
||||||
'Rupees (5)': (False, False, None, 0x35, 'Just pocket\nchange. Move\nright along.', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'a blue rupee'),
|
'Rupees (5)': (False, None, 0x35, 'Just pocket\nchange. Move\nright along.', 'the pocket change', 'poverty-struck kid', 'life lesson for sale', 'buying cheap drugs', 'destitute boy has snack again', 'a blue rupee'),
|
||||||
'Rupees (20)': (False, False, None, 0x36, 'Just couch\ncash. Move\nright along.', 'and the couch cash', 'the piggy-bank kid', 'life lesson for sale', 'the witch buying drugs', 'destitute boy has lunch again', 'a red rupee'),
|
'Rupees (20)': (False, None, 0x36, 'Just couch\ncash. Move\nright along.', 'and the couch cash', 'the piggy-bank kid', 'life lesson for sale', 'the witch buying drugs', 'destitute boy has lunch again', 'a red rupee'),
|
||||||
'Rupees (50)': (False, False, None, 0x41, 'A rupee pile!\nOkay?', 'and the rupee pile', 'the well-off kid', 'life lesson for sale', 'buying okay drugs', 'destitute boy has dinner again', 'fifty rupees'),
|
'Rupees (50)': (False, None, 0x41, 'A rupee pile!\nOkay?', 'and the rupee pile', 'the well-off kid', 'life lesson for sale', 'buying okay drugs', 'destitute boy has dinner again', 'fifty rupees'),
|
||||||
'Rupees (100)': (False, False, None, 0x40, 'A rupee stash!\nHell yeah!', 'and the rupee stash', 'the kind-of-rich kid', 'life lesson for sale', 'buying good drugs', 'affluent boy goes drinking again', 'one hundred rupees'),
|
'Rupees (100)': (False, None, 0x40, 'A rupee stash!\nHell yeah!', 'and the rupee stash', 'the kind-of-rich kid', 'life lesson for sale', 'buying good drugs', 'affluent boy goes drinking again', 'one hundred rupees'),
|
||||||
'Rupees (300)': (False, False, None, 0x46, 'A rupee hoard!\nHell yeah!', 'and the rupee hoard', 'the really-rich kid', 'life lesson for sale', 'buying the best drugs', 'fat-cat boy is rich again', 'three hundred rupees'),
|
'Rupees (300)': (False, None, 0x46, 'A rupee hoard!\nHell yeah!', 'and the rupee hoard', 'the really-rich kid', 'life lesson for sale', 'buying the best drugs', 'fat-cat boy is rich again', 'three hundred rupees'),
|
||||||
'Rupoor': (False, False, None, 0x59, 'a debt collector', 'and the toll-booth', 'the toll-booth kid', 'double loss for sale', 'witch stole your rupees', 'affluent boy steals rupees', 'a rupoor'),
|
'Rupoor': (False, None, 0x59, 'a debt collector', 'and the toll-booth', 'the toll-booth kid', 'double loss for sale', 'witch stole your rupees', 'affluent boy steals rupees', 'a rupoor'),
|
||||||
'Red Clock': (False, True, None, 0x5B, 'a waste of time', 'the ruby clock', 'the ruby-time kid', 'red time for sale', 'for ruby time', 'moment boy travels time again', 'a red clock'),
|
'Red Clock': (False, None, 0x5B, 'a waste of time', 'the ruby clock', 'the ruby-time kid', 'red time for sale', 'for ruby time', 'moment boy travels time again', 'a red clock'),
|
||||||
'Blue Clock': (False, True, None, 0x5C, 'a bit of time', 'the sapphire clock', 'sapphire-time kid', 'blue time for sale', 'for sapphire time', 'moment boy time travels again', 'a blue clock'),
|
'Blue Clock': (False, None, 0x5C, 'a bit of time', 'the sapphire clock', 'sapphire-time kid', 'blue time for sale', 'for sapphire time', 'moment boy time travels again', 'a blue clock'),
|
||||||
'Green Clock': (False, True, None, 0x5D, 'a lot of time', 'the emerald clock', 'the emerald-time kid', 'green time for sale', 'for emerald time', 'moment boy adjusts time again', 'a red clock'),
|
'Green Clock': (False, None, 0x5D, 'a lot of time', 'the emerald clock', 'the emerald-time kid', 'green time for sale', 'for emerald time', 'moment boy adjusts time again', 'a red clock'),
|
||||||
'Single RNG': (False, True, None, 0x62, 'something you don\'t yet have', None, None, None, None, 'unknown boy somethings again', 'a new mystery'),
|
'Single RNG': (False, None, 0x62, 'something you don\'t yet have', None, None, None, None, 'unknown boy somethings again', 'a new mystery'),
|
||||||
'Multi RNG': (False, True, None, 0x63, 'something you may already have', None, None, None, None, 'unknown boy somethings again', 'a total mystery'),
|
'Multi RNG': (False, None, 0x63, 'something you may already have', None, None, None, None, 'unknown boy somethings again', 'a total mystery'),
|
||||||
'Magic Upgrade (1/2)': (True, False, None, 0x4E, 'Your magic\npower has been\ndoubled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Half Magic'), # can be required to beat mothula in an open seed in very very rare circumstance
|
'Magic Upgrade (1/2)': (True, None, 0x4E, 'Your magic\npower has been\ndoubled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Half Magic'), # can be required to beat mothula in an open seed in very very rare circumstance
|
||||||
'Magic Upgrade (1/4)': (True, False, None, 0x4F, 'Your magic\npower has been\nquadrupled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Quarter Magic'), # can be required to beat mothula in an open seed in very very rare circumstance
|
'Magic Upgrade (1/4)': (True, None, 0x4F, 'Your magic\npower has been\nquadrupled!', 'and the spell power', 'the magic-saving kid', 'wizardry for sale', 'mekalekahi mekahiney ho', 'magic boy saves magic again', 'Quarter Magic'), # can be required to beat mothula in an open seed in very very rare circumstance
|
||||||
'Small Key (Eastern Palace)': (False, False, 'SmallKey', 0xA2, 'A small key to Armos Knights', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Eastern Palace'),
|
'Small Key (Eastern Palace)': (False, 'SmallKey', 0xA2, 'A small key to Armos Knights', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Eastern Palace'),
|
||||||
'Big Key (Eastern Palace)': (False, False, 'BigKey', 0x9D, 'A big key to Armos Knights', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Eastern Palace'),
|
'Big Key (Eastern Palace)': (False, 'BigKey', 0x9D, 'A big key to Armos Knights', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Eastern Palace'),
|
||||||
'Compass (Eastern Palace)': (False, True, 'Compass', 0x8D, 'Now you can find the Armos Knights!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Eastern Palace'),
|
'Compass (Eastern Palace)': (False, 'Compass', 0x8D, 'Now you can find the Armos Knights!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Eastern Palace'),
|
||||||
'Map (Eastern Palace)': (False, True, 'Map', 0x7D, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Eastern Palace'),
|
'Map (Eastern Palace)': (False, 'Map', 0x7D, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Eastern Palace'),
|
||||||
'Small Key (Desert Palace)': (False, False, 'SmallKey', 0xA3, 'A small key to the desert', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Desert Palace'),
|
'Small Key (Desert Palace)': (False, 'SmallKey', 0xA3, 'A small key to the desert', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Desert Palace'),
|
||||||
'Big Key (Desert Palace)': (False, False, 'BigKey', 0x9C, 'A big key to the desert', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Desert Palace'),
|
'Big Key (Desert Palace)': (False, 'BigKey', 0x9C, 'A big key to the desert', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Desert Palace'),
|
||||||
'Compass (Desert Palace)': (False, True, 'Compass', 0x8C, 'Now you can find Lanmolas!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Desert Palace'),
|
'Compass (Desert Palace)': (False, 'Compass', 0x8C, 'Now you can find Lanmolas!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Desert Palace'),
|
||||||
'Map (Desert Palace)': (False, True, 'Map', 0x7C, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Desert Palace'),
|
'Map (Desert Palace)': (False, 'Map', 0x7C, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Desert Palace'),
|
||||||
'Small Key (Tower of Hera)': (False, False, 'SmallKey', 0xAA, 'A small key to Hera', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Tower of Hera'),
|
'Small Key (Tower of Hera)': (False, 'SmallKey', 0xAA, 'A small key to Hera', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Tower of Hera'),
|
||||||
'Big Key (Tower of Hera)': (False, False, 'BigKey', 0x95, 'A big key to Hera', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Tower of Hera'),
|
'Big Key (Tower of Hera)': (False, 'BigKey', 0x95, 'A big key to Hera', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Tower of Hera'),
|
||||||
'Compass (Tower of Hera)': (False, True, 'Compass', 0x85, 'Now you can find Moldorm!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Tower of Hera'),
|
'Compass (Tower of Hera)': (False, 'Compass', 0x85, 'Now you can find Moldorm!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Tower of Hera'),
|
||||||
'Map (Tower of Hera)': (False, True, 'Map', 0x75, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Tower of Hera'),
|
'Map (Tower of Hera)': (False, 'Map', 0x75, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Tower of Hera'),
|
||||||
'Small Key (Hyrule Castle)': (False, False, 'SmallKey', 0xA0, 'A small key to the castle', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Hyrule Castle'),
|
'Small Key (Hyrule Castle)': (False, 'SmallKey', 0xA0, 'A small key to the castle', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Hyrule Castle'),
|
||||||
'Big Key (Hyrule Castle)': (False, False, 'BigKey', 0x9F, 'A big key to the castle', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Hyrule Castle'),
|
'Big Key (Hyrule Castle)': (False, 'BigKey', 0x9F, 'A big key to the castle', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Hyrule Castle'),
|
||||||
'Compass (Hyrule Castle)': (False, True, 'Compass', 0x8F, 'Now you can find no boss!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Hyrule Castle'),
|
'Compass (Hyrule Castle)': (False, 'Compass', 0x8F, 'Now you can find no boss!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Hyrule Castle'),
|
||||||
'Map (Hyrule Castle)': (False, True, 'Map', 0x7F, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Hyrule Castle'),
|
'Map (Hyrule Castle)': (False, 'Map', 0x7F, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Hyrule Castle'),
|
||||||
'Small Key (Agahnims Tower)': (False, False, 'SmallKey', 0xA4, 'A small key to Agahnim', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Castle Tower'),
|
'Small Key (Agahnims Tower)': (False, 'SmallKey', 0xA4, 'A small key to Agahnim', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Castle Tower'),
|
||||||
# doors-specific items, baserom will not be able to understand these
|
# doors-specific items, baserom will not be able to understand these
|
||||||
'Big Key (Agahnims Tower)': (False, False, 'BigKey', 0x9B, 'A big key to Agahnim', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Castle Tower'),
|
'Big Key (Agahnims Tower)': (False, 'BigKey', 0x9B, 'A big key to Agahnim', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Castle Tower'),
|
||||||
'Compass (Agahnims Tower)': (False, True, 'Compass', 0x8B, 'Now you can find Aga1!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds null again', 'a compass to Castle Tower'),
|
'Compass (Agahnims Tower)': (False, 'Compass', 0x8B, 'Now you can find Aga1!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds null again', 'a compass to Castle Tower'),
|
||||||
'Map (Agahnims Tower)': (False, True, 'Map', 0x7B, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Castle Tower'),
|
'Map (Agahnims Tower)': (False, 'Map', 0x7B, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Castle Tower'),
|
||||||
# end of doors-specific items
|
# end of doors-specific items
|
||||||
'Small Key (Palace of Darkness)': (False, False, 'SmallKey', 0xA6, 'A small key to darkness', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Palace of Darkness'),
|
'Small Key (Palace of Darkness)': (False, 'SmallKey', 0xA6, 'A small key to darkness', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Palace of Darkness'),
|
||||||
'Big Key (Palace of Darkness)': (False, False, 'BigKey', 0x99, 'A big key to darkness', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Palace of Darkness'),
|
'Big Key (Palace of Darkness)': (False, 'BigKey', 0x99, 'A big key to darkness', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Palace of Darkness'),
|
||||||
'Compass (Palace of Darkness)': (False, True, 'Compass', 0x89, 'Now you can find Helmasaur King!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Palace of Darkness'),
|
'Compass (Palace of Darkness)': (False, 'Compass', 0x89, 'Now you can find Helmasaur King!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Palace of Darkness'),
|
||||||
'Map (Palace of Darkness)': (False, True, 'Map', 0x79, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Palace of Darkness'),
|
'Map (Palace of Darkness)': (False, 'Map', 0x79, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Palace of Darkness'),
|
||||||
'Small Key (Thieves Town)': (False, False, 'SmallKey', 0xAB, 'A small key to thievery', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Thieves\' Town'),
|
'Small Key (Thieves Town)': (False, 'SmallKey', 0xAB, 'A small key to thievery', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Thieves\' Town'),
|
||||||
'Big Key (Thieves Town)': (False, False, 'BigKey', 0x94, 'A big key to thievery', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Thieves\' Town'),
|
'Big Key (Thieves Town)': (False, 'BigKey', 0x94, 'A big key to thievery', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Thieves\' Town'),
|
||||||
'Compass (Thieves Town)': (False, True, 'Compass', 0x84, 'Now you can find Blind!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Thieves\' Town'),
|
'Compass (Thieves Town)': (False, 'Compass', 0x84, 'Now you can find Blind!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Thieves\' Town'),
|
||||||
'Map (Thieves Town)': (False, True, 'Map', 0x74, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Thieves\' Town'),
|
'Map (Thieves Town)': (False, 'Map', 0x74, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Thieves\' Town'),
|
||||||
'Small Key (Skull Woods)': (False, False, 'SmallKey', 0xA8, 'A small key to the woods', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Skull Woods'),
|
'Small Key (Skull Woods)': (False, 'SmallKey', 0xA8, 'A small key to the woods', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Skull Woods'),
|
||||||
'Big Key (Skull Woods)': (False, False, 'BigKey', 0x97, 'A big key to the woods', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Skull Woods'),
|
'Big Key (Skull Woods)': (False, 'BigKey', 0x97, 'A big key to the woods', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Skull Woods'),
|
||||||
'Compass (Skull Woods)': (False, True, 'Compass', 0x87, 'Now you can find Mothula!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Skull Woods'),
|
'Compass (Skull Woods)': (False, 'Compass', 0x87, 'Now you can find Mothula!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Skull Woods'),
|
||||||
'Map (Skull Woods)': (False, True, 'Map', 0x77, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Skull Woods'),
|
'Map (Skull Woods)': (False, 'Map', 0x77, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Skull Woods'),
|
||||||
'Small Key (Swamp Palace)': (False, False, 'SmallKey', 0xA5, 'A small key to the swamp', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Swamp Palace'),
|
'Small Key (Swamp Palace)': (False, 'SmallKey', 0xA5, 'A small key to the swamp', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Swamp Palace'),
|
||||||
'Big Key (Swamp Palace)': (False, False, 'BigKey', 0x9A, 'A big key to the swamp', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Swamp Palace'),
|
'Big Key (Swamp Palace)': (False, 'BigKey', 0x9A, 'A big key to the swamp', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Swamp Palace'),
|
||||||
'Compass (Swamp Palace)': (False, True, 'Compass', 0x8A, 'Now you can find Arrghus!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Swamp Palace'),
|
'Compass (Swamp Palace)': (False, 'Compass', 0x8A, 'Now you can find Arrghus!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Swamp Palace'),
|
||||||
'Map (Swamp Palace)': (False, True, 'Map', 0x7A, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Swamp Palace'),
|
'Map (Swamp Palace)': (False, 'Map', 0x7A, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Swamp Palace'),
|
||||||
'Small Key (Ice Palace)': (False, False, 'SmallKey', 0xA9, 'A small key to the iceberg', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ice Palace'),
|
'Small Key (Ice Palace)': (False, 'SmallKey', 0xA9, 'A small key to the iceberg', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ice Palace'),
|
||||||
'Big Key (Ice Palace)': (False, False, 'BigKey', 0x96, 'A big key to the iceberg', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ice Palace'),
|
'Big Key (Ice Palace)': (False, 'BigKey', 0x96, 'A big key to the iceberg', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ice Palace'),
|
||||||
'Compass (Ice Palace)': (False, True, 'Compass', 0x86, 'Now you can find Kholdstare!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ice Palace'),
|
'Compass (Ice Palace)': (False, 'Compass', 0x86, 'Now you can find Kholdstare!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ice Palace'),
|
||||||
'Map (Ice Palace)': (False, True, 'Map', 0x76, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Ice Palace'),
|
'Map (Ice Palace)': (False, 'Map', 0x76, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Ice Palace'),
|
||||||
'Small Key (Misery Mire)': (False, False, 'SmallKey', 0xA7, 'A small key to the mire', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Misery Mire'),
|
'Small Key (Misery Mire)': (False, 'SmallKey', 0xA7, 'A small key to the mire', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Misery Mire'),
|
||||||
'Big Key (Misery Mire)': (False, False, 'BigKey', 0x98, 'A big key to the mire', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Misery Mire'),
|
'Big Key (Misery Mire)': (False, 'BigKey', 0x98, 'A big key to the mire', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Misery Mire'),
|
||||||
'Compass (Misery Mire)': (False, True, 'Compass', 0x88, 'Now you can find Vitreous!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Misery Mire'),
|
'Compass (Misery Mire)': (False, 'Compass', 0x88, 'Now you can find Vitreous!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Misery Mire'),
|
||||||
'Map (Misery Mire)': (False, True, 'Map', 0x78, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Misery Mire'),
|
'Map (Misery Mire)': (False, 'Map', 0x78, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Misery Mire'),
|
||||||
'Small Key (Turtle Rock)': (False, False, 'SmallKey', 0xAC, 'A small key to the pipe maze', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Turtle Rock'),
|
'Small Key (Turtle Rock)': (False, 'SmallKey', 0xAC, 'A small key to the pipe maze', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Turtle Rock'),
|
||||||
'Big Key (Turtle Rock)': (False, False, 'BigKey', 0x93, 'A big key to the pipe maze', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Turtle Rock'),
|
'Big Key (Turtle Rock)': (False, 'BigKey', 0x93, 'A big key to the pipe maze', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Turtle Rock'),
|
||||||
'Compass (Turtle Rock)': (False, True, 'Compass', 0x83, 'Now you can find Trinexx!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Turtle Rock'),
|
'Compass (Turtle Rock)': (False, 'Compass', 0x83, 'Now you can find Trinexx!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Turtle Rock'),
|
||||||
'Map (Turtle Rock)': (False, True, 'Map', 0x73, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Turtle Rock'),
|
'Map (Turtle Rock)': (False, 'Map', 0x73, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Turtle Rock'),
|
||||||
'Small Key (Ganons Tower)': (False, False, 'SmallKey', 0xAD, 'A small key to the evil tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ganon\'s Tower'),
|
'Small Key (Ganons Tower)': (False, 'SmallKey', 0xAD, 'A small key to the evil tower', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key to Ganon\'s Tower'),
|
||||||
'Big Key (Ganons Tower)': (False, False, 'BigKey', 0x92, 'A big key to the evil tower', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ganon\'s Tower'),
|
'Big Key (Ganons Tower)': (False, 'BigKey', 0x92, 'A big key to the evil tower', 'and the big key', 'the big-unlock kid', 'big key for sale', 'face key fungus', 'key boy opens chest again', 'a big key to Ganon\'s Tower'),
|
||||||
'Compass (Ganons Tower)': (False, True, 'Compass', 0x82, 'Now you can find Agahnim!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ganon\'s Tower'),
|
'Compass (Ganons Tower)': (False, 'Compass', 0x82, 'Now you can find Agahnim!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a compass to Ganon\'s Tower'),
|
||||||
'Map (Ganons Tower)': (False, True, 'Map', 0x72, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Ganon\'s Tower'),
|
'Map (Ganons Tower)': (False, 'Map', 0x72, 'A tightly folded map rests here', 'and the map', 'cartography kid', 'map for sale', 'a map to shrooms', 'map boy navigates again', 'a map to Ganon\'s Tower'),
|
||||||
'Small Key (Universal)': (False, True, None, 0xAF, 'A small key for any door', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key'),
|
'Small Key (Universal)': (False, None, 0xAF, 'A small key for any door', 'and the key', 'the unlocking kid', 'keys for sale', 'unlock the fungus', 'key boy opens door again', 'a small key'),
|
||||||
'Nothing': (False, False, None, 0x5A, 'Some Hot Air', 'and the Nothing', 'the zen kid', 'outright theft', 'shroom theft', 'empty boy is bored again', 'nothing'),
|
'Nothing': (False, None, 0x5A, 'Some Hot Air', 'and the Nothing', 'the zen kid', 'outright theft', 'shroom theft', 'empty boy is bored again', 'nothing'),
|
||||||
'Bee Trap': (False, False, None, 0xB0, 'We will sting your face a whole lot!', 'and the sting buddies', 'the beekeeper kid', 'insects for sale', 'shroom pollenation', 'bottle boy has mad bees again', 'Friendship'),
|
'Bee Trap': (False, None, 0xB0, 'We will sting your face a whole lot!', 'and the sting buddies', 'the beekeeper kid', 'insects for sale', 'shroom pollenation', 'bottle boy has mad bees again', 'Friendship'),
|
||||||
'Faerie': (False, False, None, 0xB1, 'Save me and I will revive you', 'and the captive', 'the tingle kid','hostage for sale', 'fairy dust and shrooms', 'bottle boy has friend again', 'a faerie'),
|
'Faerie': (False, None, 0xB1, 'Save me and I will revive you', 'and the captive', 'the tingle kid','hostage for sale', 'fairy dust and shrooms', 'bottle boy has friend again', 'a faerie'),
|
||||||
'Good Bee': (False, False, None, 0xB2, 'Save me and I will sting you (sometimes)', 'and the captive', 'the tingle kid','hostage for sale', 'good dust and shrooms', 'bottle boy has friend again', 'a bee'),
|
'Good Bee': (False, None, 0xB2, 'Save me and I will sting you (sometimes)', 'and the captive', 'the tingle kid','hostage for sale', 'good dust and shrooms', 'bottle boy has friend again', 'a bee'),
|
||||||
'Magic Jar': (False, False, None, 0xB3, '', '', '','', '', '', ''),
|
'Magic Jar': (False, None, 0xB3, '', '', '','', '', '', ''),
|
||||||
'Apple': (False, False, None, 0xB4, '', '', '','', '', '', ''),
|
'Apple': (False, None, 0xB4, '', '', '','', '', '', ''),
|
||||||
# 'Hint': (False, False, None, 0xB5, '', '', '','', '', '', ''),
|
# 'Hint': (False, None, 0xB5, '', '', '','', '', '', ''),
|
||||||
# 'Bomb Trap': (False, False, None, 0xB6, '', '', '','', '', '', ''),
|
# 'Bomb Trap': (False, None, 0xB6, '', '', '','', '', '', ''),
|
||||||
'Red Potion': (False, False, None, 0x2E, 'Hearty red goop!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'a red potion'),
|
'Red Potion': (False, None, 0x2E, 'Hearty red goop!', 'and the red goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has red goo again', 'a red potion'),
|
||||||
'Green Potion': (False, False, None, 0x2F, 'Refreshing green goop!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a green potion'),
|
'Green Potion': (False, None, 0x2F, 'Refreshing green goop!', 'and the green goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has green goo again', 'a green potion'),
|
||||||
'Blue Potion': (False, False, None, 0x30, 'Delicious blue goop!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a blue potion'),
|
'Blue Potion': (False, None, 0x30, 'Delicious blue goop!', 'and the blue goo', 'the liquid kid', 'potion for sale', 'free samples', 'bottle boy has blue goo again', 'a blue potion'),
|
||||||
'Bee': (False, False, None, 0x0E, 'I will sting your foes a few times', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bee'),
|
'Bee': (False, None, 0x0E, 'I will sting your foes a few times', 'and the sting buddy', 'the beekeeper kid', 'insect for sale', 'shroom pollenation', 'bottle boy has mad bee again', 'a bee'),
|
||||||
'Small Heart': (False, False, None, 0x42, 'Just a little\npiece of love!', 'and the heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart'),
|
'Small Heart': (False, None, 0x42, 'Just a little\npiece of love!', 'and the heart', 'the life-giving kid', 'little love for sale', 'fungus for life', 'life boy feels some love again', 'a heart'),
|
||||||
'Beat Agahnim 1': (True, False, 'Event', None, None, None, None, None, None, None, None),
|
'Activated Flute': (True, None, 0x4A, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'flute boy plays again', 'the Flute'),
|
||||||
'Beat Agahnim 2': (True, False, 'Event', None, None, None, None, None, None, None, None),
|
'Beat Agahnim 1': (True, 'Event', None, None, None, None, None, None, None, None),
|
||||||
'Get Frog': (True, False, 'Event', None, None, None, None, None, None, None, None),
|
'Beat Agahnim 2': (True, 'Event', None, None, None, None, None, None, None, None),
|
||||||
'Return Smith': (True, False, 'Event', None, None, None, None, None, None, None, None),
|
'Get Frog': (True, 'Event', None, None, None, None, None, None, None, None),
|
||||||
'Pick Up Purple Chest': (True, False, 'Event', None, None, None, None, None, None, None, None),
|
'Return Smith': (True, 'Event', None, None, None, None, None, None, None, None),
|
||||||
'Open Floodgate': (True, False, 'Event', None, None, None, None, None, None, None, None),
|
'Pick Up Purple Chest': (True, 'Event', None, None, None, None, None, None, None, None),
|
||||||
|
'Open Floodgate': (True, 'Event', None, None, None, None, None, None, None, None),
|
||||||
}
|
}
|
||||||
|
|
||||||
lookup_id_to_name = {data[3]: name for name, data in item_table.items()}
|
lookup_id_to_name = {data[2]: name for name, data in item_table.items()}
|
||||||
|
|
||||||
hint_blacklist = {"Triforce"}
|
hint_blacklist = {"Triforce"}
|
||||||
|
|
||||||
|
@ -230,7 +242,9 @@ for basename, substring in _simple_groups:
|
||||||
|
|
||||||
del (_simple_groups)
|
del (_simple_groups)
|
||||||
|
|
||||||
progression_items = {name for name, data in item_table.items() if type(data[3]) == int and data[0]}
|
progression_items = {name for name, data in item_table.items() if type(data[2]) == int and data[0]}
|
||||||
item_name_groups['Everything'] = {name for name, data in item_table.items() if type(data[3]) == int}
|
item_name_groups['Everything'] = {name for name, data in item_table.items() if type(data[2]) == int}
|
||||||
item_name_groups['Progression Items'] = progression_items
|
item_name_groups['Progression Items'] = progression_items
|
||||||
item_name_groups['Non Progression Items'] = item_name_groups['Everything'] - progression_items
|
item_name_groups['Non Progression Items'] = item_name_groups['Everything'] - progression_items
|
||||||
|
|
||||||
|
trap_replaceable = item_name_groups['Rupees'] | {'Arrows (10)', 'Single Bomb', 'Bombs (3)', 'Bombs (10)', 'Nothing'}
|
||||||
|
|
4
LICENSE
4
LICENSE
|
@ -1,8 +1,8 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2017 LLCoolDave
|
Copyright (c) 2017 LLCoolDave
|
||||||
Copyright (c) 2020 Berserker66
|
Copyright (c) 2021 Berserker66
|
||||||
Copyright (c) 2020 CaitSith2
|
Copyright (c) 2021 CaitSith2
|
||||||
Copyright (c) 2020 LegendaryLinux
|
Copyright (c) 2020 LegendaryLinux
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|
98
Main.py
98
Main.py
|
@ -10,7 +10,7 @@ import zlib
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
|
|
||||||
from BaseClasses import World, CollectionState, Item, Region, Location
|
from BaseClasses import World, CollectionState, Item, Region, Location
|
||||||
from Shops import ShopSlotFill, create_shops, SHOP_ID_START, FillDisabledShopSlots
|
from Shops import ShopSlotFill, create_shops, SHOP_ID_START, FillDisabledShopSlots, total_shop_slots
|
||||||
from Items import ItemFactory, item_table, item_name_groups
|
from Items import ItemFactory, item_table, item_name_groups
|
||||||
from Regions import create_regions, mark_light_world_regions, lookup_vanilla_location_to_entrance
|
from Regions import create_regions, mark_light_world_regions, lookup_vanilla_location_to_entrance
|
||||||
from InvertedRegions import create_inverted_regions, mark_dark_world_regions
|
from InvertedRegions import create_inverted_regions, mark_dark_world_regions
|
||||||
|
@ -21,6 +21,7 @@ from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive
|
||||||
from Fill import distribute_items_restrictive, flood_items, balance_multiworld_progression, distribute_planned
|
from Fill import distribute_items_restrictive, flood_items, balance_multiworld_progression, distribute_planned
|
||||||
from ItemPool import generate_itempool, difficulties, fill_prizes
|
from ItemPool import generate_itempool, difficulties, fill_prizes
|
||||||
from Utils import output_path, parse_player_names, get_options, __version__, _version_tuple
|
from Utils import output_path, parse_player_names, get_options, __version__, _version_tuple
|
||||||
|
from typing import Dict
|
||||||
import Patch
|
import Patch
|
||||||
|
|
||||||
seeddigits = 20
|
seeddigits = 20
|
||||||
|
@ -33,6 +34,14 @@ def get_seed(seed=None):
|
||||||
return seed
|
return seed
|
||||||
|
|
||||||
|
|
||||||
|
seeds: Dict[tuple, str] = dict()
|
||||||
|
def get_same_seed(world: World, seed_def: tuple) -> str:
|
||||||
|
if seed_def in seeds:
|
||||||
|
return seeds[seed_def]
|
||||||
|
seeds[seed_def] = str(world.random.randint(0, 2 ** 64))
|
||||||
|
return seeds[seed_def]
|
||||||
|
|
||||||
|
|
||||||
def main(args, seed=None):
|
def main(args, seed=None):
|
||||||
if args.outputpath:
|
if args.outputpath:
|
||||||
os.makedirs(args.outputpath, exist_ok=True)
|
os.makedirs(args.outputpath, exist_ok=True)
|
||||||
|
@ -92,11 +101,23 @@ def main(args, seed=None):
|
||||||
world.plando_items = args.plando_items.copy()
|
world.plando_items = args.plando_items.copy()
|
||||||
world.plando_texts = args.plando_texts.copy()
|
world.plando_texts = args.plando_texts.copy()
|
||||||
world.plando_connections = args.plando_connections.copy()
|
world.plando_connections = args.plando_connections.copy()
|
||||||
|
world.er_seeds = args.er_seeds.copy()
|
||||||
world.restrict_dungeon_item_on_boss = args.restrict_dungeon_item_on_boss.copy()
|
world.restrict_dungeon_item_on_boss = args.restrict_dungeon_item_on_boss.copy()
|
||||||
world.required_medallions = args.required_medallions.copy()
|
world.required_medallions = args.required_medallions.copy()
|
||||||
|
|
||||||
world.rom_seeds = {player: random.Random(world.random.randint(0, 999999999)) for player in range(1, world.players + 1)}
|
world.rom_seeds = {player: random.Random(world.random.randint(0, 999999999)) for player in range(1, world.players + 1)}
|
||||||
|
|
||||||
|
for player in range(1, world.players+1):
|
||||||
|
world.er_seeds[player] = str(world.random.randint(0, 2 ** 64))
|
||||||
|
|
||||||
|
if "-" in world.shuffle[player]:
|
||||||
|
shuffle, seed = world.shuffle[player].split("-", 1)
|
||||||
|
world.shuffle[player] = shuffle
|
||||||
|
if seed.startswith("team-"):
|
||||||
|
world.er_seeds[player] = get_same_seed(world, (shuffle, seed, world.retro[player], world.mode[player], world.logic[player]))
|
||||||
|
else:
|
||||||
|
world.er_seeds[player] = seed
|
||||||
|
|
||||||
logger.info('ALttP Berserker\'s Multiworld Version %s - Seed: %s\n', __version__, world.seed)
|
logger.info('ALttP Berserker\'s Multiworld Version %s - Seed: %s\n', __version__, world.seed)
|
||||||
|
|
||||||
parsed_names = parse_player_names(args.names, world.players, args.teams)
|
parsed_names = parse_player_names(args.names, world.players, args.teams)
|
||||||
|
@ -112,6 +133,14 @@ def main(args, seed=None):
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
world.difficulty_requirements[player] = difficulties[world.difficulty[player]]
|
world.difficulty_requirements[player] = difficulties[world.difficulty[player]]
|
||||||
|
|
||||||
|
if world.open_pyramid[player] == 'goal':
|
||||||
|
world.open_pyramid[player] = world.goal[player] in {'crystals', 'ganontriforcehunt', 'localganontriforcehunt', 'ganonpedestal'}
|
||||||
|
elif world.open_pyramid[player] == 'auto':
|
||||||
|
world.open_pyramid[player] = world.goal[player] in {'crystals', 'ganontriforcehunt', 'localganontriforcehunt', 'ganonpedestal'} and \
|
||||||
|
(world.shuffle[player] in {'vanilla', 'dungeonssimple', 'dungeonsfull'} or not world.shuffle_ganon)
|
||||||
|
else:
|
||||||
|
world.open_pyramid[player] = {'on': True, 'off': False, 'yes': True, 'no': False}.get(world.open_pyramid[player], world.open_pyramid[player])
|
||||||
|
|
||||||
for tok in filter(None, args.startinventory[player].split(',')):
|
for tok in filter(None, args.startinventory[player].split(',')):
|
||||||
item = ItemFactory(tok.strip(), player)
|
item = ItemFactory(tok.strip(), player)
|
||||||
if item:
|
if item:
|
||||||
|
@ -162,12 +191,18 @@ def main(args, seed=None):
|
||||||
{"vanilla", "dungeonssimple", "dungeonsfull", "simple", "restricted", "full"}:
|
{"vanilla", "dungeonssimple", "dungeonsfull", "simple", "restricted", "full"}:
|
||||||
world.fix_fake_world[player] = False
|
world.fix_fake_world[player] = False
|
||||||
|
|
||||||
|
# seeded entrance shuffle
|
||||||
|
old_random = world.random
|
||||||
|
world.random = random.Random(world.er_seeds[player])
|
||||||
|
|
||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
link_entrances(world, player)
|
link_entrances(world, player)
|
||||||
mark_light_world_regions(world, player)
|
mark_light_world_regions(world, player)
|
||||||
else:
|
else:
|
||||||
link_inverted_entrances(world, player)
|
link_inverted_entrances(world, player)
|
||||||
mark_dark_world_regions(world, player)
|
mark_dark_world_regions(world, player)
|
||||||
|
|
||||||
|
world.random = old_random
|
||||||
plando_connect(world, player)
|
plando_connect(world, player)
|
||||||
|
|
||||||
logger.info('Generating Item Pool.')
|
logger.info('Generating Item Pool.')
|
||||||
|
@ -208,13 +243,13 @@ def main(args, seed=None):
|
||||||
elif args.algorithm == 'balanced':
|
elif args.algorithm == 'balanced':
|
||||||
distribute_items_restrictive(world, True)
|
distribute_items_restrictive(world, True)
|
||||||
|
|
||||||
if world.players > 1:
|
|
||||||
balance_multiworld_progression(world)
|
|
||||||
|
|
||||||
logger.info("Filling Shop Slots")
|
logger.info("Filling Shop Slots")
|
||||||
|
|
||||||
ShopSlotFill(world)
|
ShopSlotFill(world)
|
||||||
|
|
||||||
|
if world.players > 1:
|
||||||
|
balance_multiworld_progression(world)
|
||||||
|
|
||||||
logger.info('Patching ROM.')
|
logger.info('Patching ROM.')
|
||||||
|
|
||||||
|
|
||||||
|
@ -251,7 +286,7 @@ def main(args, seed=None):
|
||||||
|
|
||||||
apply_rom_settings(rom, args.heartbeep[player], args.heartcolor[player], args.quickswap[player],
|
apply_rom_settings(rom, args.heartbeep[player], args.heartcolor[player], args.quickswap[player],
|
||||||
args.fastmenu[player], args.disablemusic[player], args.triforcehud[player], args.sprite[player],
|
args.fastmenu[player], args.disablemusic[player], args.triforcehud[player], args.sprite[player],
|
||||||
palettes_options, world, player, True)
|
palettes_options, world, player, True, reduceflashing=args.reduceflashing[player] if not args.race else True)
|
||||||
|
|
||||||
mcsb_name = ''
|
mcsb_name = ''
|
||||||
if all([world.mapshuffle[player], world.compassshuffle[player], world.keyshuffle[player],
|
if all([world.mapshuffle[player], world.compassshuffle[player], world.keyshuffle[player],
|
||||||
|
@ -277,7 +312,7 @@ def main(args, seed=None):
|
||||||
outfilestuffs = {
|
outfilestuffs = {
|
||||||
"logic": world.logic[player], # 0
|
"logic": world.logic[player], # 0
|
||||||
"difficulty": world.difficulty[player], # 1
|
"difficulty": world.difficulty[player], # 1
|
||||||
"difficulty_adjustments": world.difficulty_adjustments[player], # 2
|
"item_functionality": world.item_functionality[player], # 2
|
||||||
"mode": world.mode[player], # 3
|
"mode": world.mode[player], # 3
|
||||||
"goal": world.goal[player], # 4
|
"goal": world.goal[player], # 4
|
||||||
"timer": str(world.timer[player]), # 5
|
"timer": str(world.timer[player]), # 5
|
||||||
|
@ -298,7 +333,7 @@ def main(args, seed=None):
|
||||||
outfilestuffs["logic"], # 0
|
outfilestuffs["logic"], # 0
|
||||||
|
|
||||||
outfilestuffs["difficulty"], # 1
|
outfilestuffs["difficulty"], # 1
|
||||||
outfilestuffs["difficulty_adjustments"], # 2
|
outfilestuffs["item_functionality"], # 2
|
||||||
outfilestuffs["mode"], # 3
|
outfilestuffs["mode"], # 3
|
||||||
outfilestuffs["goal"], # 4
|
outfilestuffs["goal"], # 4
|
||||||
"" if outfilestuffs["timer"] in ['False', 'none', 'display'] else "-" + outfilestuffs["timer"], # 5
|
"" if outfilestuffs["timer"] in ['False', 'none', 'display'] else "-" + outfilestuffs["timer"], # 5
|
||||||
|
@ -371,18 +406,21 @@ def main(args, seed=None):
|
||||||
checks_in_area[location.player]["Total"] += 1
|
checks_in_area[location.player]["Total"] += 1
|
||||||
|
|
||||||
oldmancaves = []
|
oldmancaves = []
|
||||||
for region in [world.get_region("Old Man Sword Cave", player) for player in range(1, world.players + 1) if world.retro[player]]:
|
takeanyregions = ["Old Man Sword Cave", "Take-Any #1", "Take-Any #2", "Take-Any #3", "Take-Any #4"]
|
||||||
item = ItemFactory(region.shop.inventory[0]['item'], region.player)
|
for index, take_any in enumerate(takeanyregions):
|
||||||
|
for region in [world.get_region(take_any, player) for player in range(1, world.players + 1) if world.retro[player]]:
|
||||||
|
item = ItemFactory(region.shop.inventory[(0 if take_any == "Old Man Sword Cave" else 1)]['item'], region.player)
|
||||||
player = region.player
|
player = region.player
|
||||||
location_id = SHOP_ID_START + 33
|
location_id = SHOP_ID_START + total_shop_slots + index
|
||||||
|
|
||||||
if region.type == RegionType.LightWorld:
|
main_entrance = get_entrance_to_region(region)
|
||||||
|
if main_entrance.parent_region.type == RegionType.LightWorld:
|
||||||
checks_in_area[player]["Light World"].append(location_id)
|
checks_in_area[player]["Light World"].append(location_id)
|
||||||
else:
|
else:
|
||||||
checks_in_area[player]["Dark World"].append(location_id)
|
checks_in_area[player]["Dark World"].append(location_id)
|
||||||
checks_in_area[player]["Total"] += 1
|
checks_in_area[player]["Total"] += 1
|
||||||
|
|
||||||
er_hint_data[player][location_id] = get_entrance_to_region(region).name
|
er_hint_data[player][location_id] = main_entrance.name
|
||||||
oldmancaves.append(((location_id, player), (item.code, player)))
|
oldmancaves.append(((location_id, player), (item.code, player)))
|
||||||
|
|
||||||
precollected_items = [[] for player in range(world.players)]
|
precollected_items = [[] for player in range(world.players)]
|
||||||
|
@ -449,9 +487,10 @@ def main(args, seed=None):
|
||||||
return world
|
return world
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def copy_world(world):
|
def copy_world(world):
|
||||||
# ToDo: Not good yet
|
# ToDo: Not good yet
|
||||||
ret = World(world.players, world.shuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints)
|
ret = World(world.players, world.shuffle, world.logic, world.mode, world.swords, world.difficulty, world.item_functionality, world.timer, world.progressive, world.goal, world.algorithm, world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints)
|
||||||
ret.teams = world.teams
|
ret.teams = world.teams
|
||||||
ret.player_names = copy.deepcopy(world.player_names)
|
ret.player_names = copy.deepcopy(world.player_names)
|
||||||
ret.remote_items = world.remote_items.copy()
|
ret.remote_items = world.remote_items.copy()
|
||||||
|
@ -524,7 +563,7 @@ def copy_world(world):
|
||||||
# fill locations
|
# fill locations
|
||||||
for location in world.get_locations():
|
for location in world.get_locations():
|
||||||
if location.item is not None:
|
if location.item is not None:
|
||||||
item = Item(location.item.name, location.item.advancement, location.item.priority, location.item.type, player = location.item.player)
|
item = Item(location.item.name, location.item.advancement, location.item.type, player = location.item.player)
|
||||||
ret.get_location(location.name, location.player).item = item
|
ret.get_location(location.name, location.player).item = item
|
||||||
item.location = ret.get_location(location.name, location.player)
|
item.location = ret.get_location(location.name, location.player)
|
||||||
item.world = ret
|
item.world = ret
|
||||||
|
@ -535,7 +574,7 @@ def copy_world(world):
|
||||||
|
|
||||||
# copy remaining itempool. No item in itempool should have an assigned location
|
# copy remaining itempool. No item in itempool should have an assigned location
|
||||||
for item in world.itempool:
|
for item in world.itempool:
|
||||||
ret.itempool.append(Item(item.name, item.advancement, item.priority, item.type, player = item.player))
|
ret.itempool.append(Item(item.name, item.advancement, item.type, player = item.player))
|
||||||
|
|
||||||
for item in world.precollected_items:
|
for item in world.precollected_items:
|
||||||
ret.push_precollected(ItemFactory(item.name, item.player))
|
ret.push_precollected(ItemFactory(item.name, item.player))
|
||||||
|
@ -593,11 +632,11 @@ def create_playthrough(world):
|
||||||
while sphere_candidates:
|
while sphere_candidates:
|
||||||
state.sweep_for_events(key_only=True)
|
state.sweep_for_events(key_only=True)
|
||||||
|
|
||||||
sphere = []
|
sphere = set()
|
||||||
# build up spheres of collection radius. Everything in each sphere is independent from each other in dependencies and only depends on lower spheres
|
# build up spheres of collection radius. Everything in each sphere is independent from each other in dependencies and only depends on lower spheres
|
||||||
for location in sphere_candidates:
|
for location in sphere_candidates:
|
||||||
if state.can_reach(location):
|
if state.can_reach(location):
|
||||||
sphere.append(location)
|
sphere.add(location)
|
||||||
|
|
||||||
for location in sphere:
|
for location in sphere:
|
||||||
sphere_candidates.remove(location)
|
sphere_candidates.remove(location)
|
||||||
|
@ -621,25 +660,24 @@ def create_playthrough(world):
|
||||||
break
|
break
|
||||||
|
|
||||||
# in the second phase, we cull each sphere such that the game is still beatable, reducing each range of influence to the bare minimum required inside it
|
# in the second phase, we cull each sphere such that the game is still beatable, reducing each range of influence to the bare minimum required inside it
|
||||||
for num, sphere in reversed(list(enumerate(collection_spheres))):
|
for num, sphere in reversed(tuple(enumerate(collection_spheres))):
|
||||||
to_delete = []
|
to_delete = set()
|
||||||
for location in sphere:
|
for location in sphere:
|
||||||
# we remove the item at location and check if game is still beatable
|
# we remove the item at location and check if game is still beatable
|
||||||
logging.getLogger('').debug('Checking if %s (Player %d) is required to beat the game.', location.item.name, location.item.player)
|
logging.getLogger('').debug('Checking if %s (Player %d) is required to beat the game.', location.item.name, location.item.player)
|
||||||
old_item = location.item
|
old_item = location.item
|
||||||
location.item = None
|
location.item = None
|
||||||
if world.can_beat_game(state_cache[num]):
|
if world.can_beat_game(state_cache[num]):
|
||||||
to_delete.append(location)
|
to_delete.add(location)
|
||||||
else:
|
else:
|
||||||
# still required, got to keep it around
|
# still required, got to keep it around
|
||||||
location.item = old_item
|
location.item = old_item
|
||||||
|
|
||||||
# cull entries in spheres for spoiler walkthrough at end
|
# cull entries in spheres for spoiler walkthrough at end
|
||||||
for location in to_delete:
|
sphere -= to_delete
|
||||||
sphere.remove(location)
|
|
||||||
|
|
||||||
# second phase, sphere 0
|
# second phase, sphere 0
|
||||||
for item in [i for i in world.precollected_items if i.advancement]:
|
for item in (i for i in world.precollected_items if i.advancement):
|
||||||
logging.getLogger('').debug('Checking if %s (Player %d) is required to beat the game.', item.name, item.player)
|
logging.getLogger('').debug('Checking if %s (Player %d) is required to beat the game.', item.name, item.player)
|
||||||
world.precollected_items.remove(item)
|
world.precollected_items.remove(item)
|
||||||
world.state.remove(item)
|
world.state.remove(item)
|
||||||
|
@ -652,13 +690,13 @@ def create_playthrough(world):
|
||||||
# used to access it was deemed not required.) So we need to do one final sphere collection pass
|
# used to access it was deemed not required.) So we need to do one final sphere collection pass
|
||||||
# to build up the correct spheres
|
# to build up the correct spheres
|
||||||
|
|
||||||
required_locations = [item for sphere in collection_spheres for item in sphere]
|
required_locations = {item for sphere in collection_spheres for item in sphere}
|
||||||
state = CollectionState(world)
|
state = CollectionState(world)
|
||||||
collection_spheres = []
|
collection_spheres = []
|
||||||
while required_locations:
|
while required_locations:
|
||||||
state.sweep_for_events(key_only=True)
|
state.sweep_for_events(key_only=True)
|
||||||
|
|
||||||
sphere = list(filter(state.can_reach, required_locations))
|
sphere = set(filter(state.can_reach, required_locations))
|
||||||
|
|
||||||
for location in sphere:
|
for location in sphere:
|
||||||
required_locations.remove(location)
|
required_locations.remove(location)
|
||||||
|
@ -670,9 +708,6 @@ def create_playthrough(world):
|
||||||
if not sphere:
|
if not sphere:
|
||||||
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
|
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
|
||||||
|
|
||||||
# store the required locations for statistical analysis
|
|
||||||
old_world.required_locations = [(location.name, location.player) for sphere in collection_spheres for location in sphere]
|
|
||||||
|
|
||||||
def flist_to_iter(node):
|
def flist_to_iter(node):
|
||||||
while node:
|
while node:
|
||||||
value, node = node
|
value, node = node
|
||||||
|
@ -689,7 +724,7 @@ def create_playthrough(world):
|
||||||
old_world.spoiler.paths = dict()
|
old_world.spoiler.paths = dict()
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
old_world.spoiler.paths.update({ str(location) : get_path(state, location.parent_region) for sphere in collection_spheres for location in sphere if location.player == player})
|
old_world.spoiler.paths.update({ str(location) : get_path(state, location.parent_region) for sphere in collection_spheres for location in sphere if location.player == player})
|
||||||
for _, path in dict(old_world.spoiler.paths).items():
|
for path in dict(old_world.spoiler.paths).values():
|
||||||
if any(exit == 'Pyramid Fairy' for (_, exit) in path):
|
if any(exit == 'Pyramid Fairy' for (_, exit) in path):
|
||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
old_world.spoiler.paths[str(world.get_region('Big Bomb Shop', player))] = get_path(state, world.get_region('Big Bomb Shop', player))
|
old_world.spoiler.paths[str(world.get_region('Big Bomb Shop', player))] = get_path(state, world.get_region('Big Bomb Shop', player))
|
||||||
|
@ -697,6 +732,7 @@ def create_playthrough(world):
|
||||||
old_world.spoiler.paths[str(world.get_region('Inverted Big Bomb Shop', player))] = get_path(state, world.get_region('Inverted Big Bomb Shop', player))
|
old_world.spoiler.paths[str(world.get_region('Inverted Big Bomb Shop', player))] = get_path(state, world.get_region('Inverted Big Bomb Shop', player))
|
||||||
|
|
||||||
# we can finally output our playthrough
|
# we can finally output our playthrough
|
||||||
old_world.spoiler.playthrough = OrderedDict([("0", [str(item) for item in world.precollected_items if item.advancement])])
|
old_world.spoiler.playthrough = {"0": sorted([str(item) for item in world.precollected_items if item.advancement])}
|
||||||
|
|
||||||
for i, sphere in enumerate(collection_spheres):
|
for i, sphere in enumerate(collection_spheres):
|
||||||
old_world.spoiler.playthrough[str(i + 1)] = {str(location): str(location.item) for location in sphere}
|
old_world.spoiler.playthrough[str(i + 1)] = {str(location): str(location.item) for location in sorted(sphere)}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import WebUI
|
||||||
|
|
||||||
import Regions
|
import Regions
|
||||||
import Utils
|
import Utils
|
||||||
|
import Items
|
||||||
|
|
||||||
# logging note:
|
# logging note:
|
||||||
# logging.* gets send to only the text console, logger.* gets send to the WebUI as well, if it's initialized.
|
# logging.* gets send to only the text console, logger.* gets send to the WebUI as well, if it's initialized.
|
||||||
|
@ -140,6 +141,13 @@ def color(text, *args):
|
||||||
return color_code(*args) + text + color_code('reset')
|
return color_code(*args) + text + color_code('reset')
|
||||||
|
|
||||||
|
|
||||||
|
def color_item(item_id: int, green: bool = False) -> str:
|
||||||
|
item_name = get_item_name_from_id(item_id)
|
||||||
|
item_colors = ['green' if green else 'cyan']
|
||||||
|
if item_name in Items.progression_items:
|
||||||
|
item_colors.append("white_bg")
|
||||||
|
return color(item_name, *item_colors)
|
||||||
|
|
||||||
START_RECONNECT_DELAY = 5
|
START_RECONNECT_DELAY = 5
|
||||||
SNES_RECONNECT_DELAY = 5
|
SNES_RECONNECT_DELAY = 5
|
||||||
SERVER_RECONNECT_DELAY = 5
|
SERVER_RECONNECT_DELAY = 5
|
||||||
|
@ -931,8 +939,9 @@ async def process_server_cmd(ctx: Context, cmd, args):
|
||||||
player_sent, location, player_recvd, item = args
|
player_sent, location, player_recvd, item = args
|
||||||
ctx.ui_node.notify_item_sent(ctx.player_names[player_sent], ctx.player_names[player_recvd],
|
ctx.ui_node.notify_item_sent(ctx.player_names[player_sent], ctx.player_names[player_recvd],
|
||||||
get_item_name_from_id(item), get_location_name_from_address(location),
|
get_item_name_from_id(item), get_location_name_from_address(location),
|
||||||
player_sent == ctx.slot, player_recvd == ctx.slot)
|
player_sent == ctx.slot, player_recvd == ctx.slot,
|
||||||
item = color(get_item_name_from_id(item), 'cyan' if player_sent != ctx.slot else 'green')
|
get_item_name_from_id(item) in Items.progression_items)
|
||||||
|
item = color_item(item, player_sent == ctx.slot)
|
||||||
player_sent = color(ctx.player_names[player_sent], 'yellow' if player_sent != ctx.slot else 'magenta')
|
player_sent = color(ctx.player_names[player_sent], 'yellow' if player_sent != ctx.slot else 'magenta')
|
||||||
player_recvd = color(ctx.player_names[player_recvd], 'yellow' if player_recvd != ctx.slot else 'magenta')
|
player_recvd = color(ctx.player_names[player_recvd], 'yellow' if player_recvd != ctx.slot else 'magenta')
|
||||||
logging.info(
|
logging.info(
|
||||||
|
@ -942,8 +951,9 @@ async def process_server_cmd(ctx: Context, cmd, args):
|
||||||
elif cmd == 'ItemFound':
|
elif cmd == 'ItemFound':
|
||||||
found = ReceivedItem(*args)
|
found = ReceivedItem(*args)
|
||||||
ctx.ui_node.notify_item_found(ctx.player_names[found.player], get_item_name_from_id(found.item),
|
ctx.ui_node.notify_item_found(ctx.player_names[found.player], get_item_name_from_id(found.item),
|
||||||
get_location_name_from_address(found.location), found.player == ctx.slot)
|
get_location_name_from_address(found.location), found.player == ctx.slot,
|
||||||
item = color(get_item_name_from_id(found.item), 'cyan' if found.player != ctx.slot else 'green')
|
get_item_name_from_id(found.item) in Items.progression_items)
|
||||||
|
item = color_item(found.item, found.player == ctx.slot)
|
||||||
player_sent = color(ctx.player_names[found.player], 'yellow' if found.player != ctx.slot else 'magenta')
|
player_sent = color(ctx.player_names[found.player], 'yellow' if found.player != ctx.slot else 'magenta')
|
||||||
logging.info('%s found %s (%s)' % (player_sent, item, color(get_location_name_from_address(found.location),
|
logging.info('%s found %s (%s)' % (player_sent, item, color(get_location_name_from_address(found.location),
|
||||||
'blue_bg', 'white')))
|
'blue_bg', 'white')))
|
||||||
|
@ -968,7 +978,7 @@ async def process_server_cmd(ctx: Context, cmd, args):
|
||||||
get_item_name_from_id(hint.item), get_location_name_from_address(hint.location),
|
get_item_name_from_id(hint.item), get_location_name_from_address(hint.location),
|
||||||
hint.found, hint.finding_player == ctx.slot, hint.receiving_player == ctx.slot,
|
hint.found, hint.finding_player == ctx.slot, hint.receiving_player == ctx.slot,
|
||||||
hint.entrance if hint.entrance else None)
|
hint.entrance if hint.entrance else None)
|
||||||
item = color(get_item_name_from_id(hint.item), 'green' if hint.found else 'cyan')
|
item = color_item(hint.item, hint.found)
|
||||||
player_find = color(ctx.player_names[hint.finding_player],
|
player_find = color(ctx.player_names[hint.finding_player],
|
||||||
'yellow' if hint.finding_player != ctx.slot else 'magenta')
|
'yellow' if hint.finding_player != ctx.slot else 'magenta')
|
||||||
player_recvd = color(ctx.player_names[hint.receiving_player],
|
player_recvd = color(ctx.player_names[hint.receiving_player],
|
||||||
|
@ -1078,7 +1088,8 @@ class ClientCommandProcessor(CommandProcessor):
|
||||||
for index, item in enumerate(self.ctx.items_received, 1):
|
for index, item in enumerate(self.ctx.items_received, 1):
|
||||||
self.ctx.ui_node.notify_item_received(self.ctx.player_names[item.player], get_item_name_from_id(item.item),
|
self.ctx.ui_node.notify_item_received(self.ctx.player_names[item.player], get_item_name_from_id(item.item),
|
||||||
get_location_name_from_address(item.location), index,
|
get_location_name_from_address(item.location), index,
|
||||||
len(self.ctx.items_received))
|
len(self.ctx.items_received),
|
||||||
|
get_item_name_from_id(item.item) in Items.progression_items)
|
||||||
logging.info('%s from %s (%s) (%d/%d in list)' % (
|
logging.info('%s from %s (%s) (%d/%d in list)' % (
|
||||||
color(get_item_name_from_id(item.item), 'red', 'bold'),
|
color(get_item_name_from_id(item.item), 'red', 'bold'),
|
||||||
color(self.ctx.player_names[item.player], 'yellow'),
|
color(self.ctx.player_names[item.player], 'yellow'),
|
||||||
|
@ -1336,7 +1347,8 @@ async def game_watcher(ctx : Context):
|
||||||
item = ctx.items_received[recv_index]
|
item = ctx.items_received[recv_index]
|
||||||
ctx.ui_node.notify_item_received(ctx.player_names[item.player], get_item_name_from_id(item.item),
|
ctx.ui_node.notify_item_received(ctx.player_names[item.player], get_item_name_from_id(item.item),
|
||||||
get_location_name_from_address(item.location), recv_index + 1,
|
get_location_name_from_address(item.location), recv_index + 1,
|
||||||
len(ctx.items_received))
|
len(ctx.items_received),
|
||||||
|
get_item_name_from_id(item.item) in Items.progression_items)
|
||||||
logging.info('Received %s from %s (%s) (%d/%d in list)' % (
|
logging.info('Received %s from %s (%s) (%d/%d in list)' % (
|
||||||
color(get_item_name_from_id(item.item), 'red', 'bold'), color(ctx.player_names[item.player], 'yellow'),
|
color(get_item_name_from_id(item.item), 'red', 'bold'), color(ctx.player_names[item.player], 'yellow'),
|
||||||
get_location_name_from_address(item.location), recv_index + 1, len(ctx.items_received)))
|
get_location_name_from_address(item.location), recv_index + 1, len(ctx.items_received)))
|
||||||
|
|
|
@ -539,7 +539,7 @@ def notify_team(ctx: Context, team: int, text: str):
|
||||||
|
|
||||||
def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[Utils.Hint]:
|
def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[Utils.Hint]:
|
||||||
hints = []
|
hints = []
|
||||||
seeked_item_id = Items.item_table[item][3]
|
seeked_item_id = Items.item_table[item][2]
|
||||||
for check, result in ctx.locations.items():
|
for check, result in ctx.locations.items():
|
||||||
item_id, receiving_player = result
|
item_id, receiving_player = result
|
||||||
if receiving_player == slot and item_id == seeked_item_id:
|
if receiving_player == slot and item_id == seeked_item_id:
|
||||||
|
@ -875,7 +875,7 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
||||||
if self.ctx.item_cheat:
|
if self.ctx.item_cheat:
|
||||||
item_name, usable, response = get_intended_text(item_name, Items.item_table.keys())
|
item_name, usable, response = get_intended_text(item_name, Items.item_table.keys())
|
||||||
if usable:
|
if usable:
|
||||||
new_item = ReceivedItem(Items.item_table[item_name][3], -1, self.client.slot)
|
new_item = ReceivedItem(Items.item_table[item_name][2], -1, self.client.slot)
|
||||||
get_received_items(self.ctx, self.client.team, self.client.slot).append(new_item)
|
get_received_items(self.ctx, self.client.team, self.client.slot).append(new_item)
|
||||||
self.ctx.notify_all('Cheat console: sending "' + item_name + '" to ' + self.ctx.get_aliased_name(self.client.team, self.client.slot))
|
self.ctx.notify_all('Cheat console: sending "' + item_name + '" to ' + self.ctx.get_aliased_name(self.client.team, self.client.slot))
|
||||||
send_new_items(self.ctx)
|
send_new_items(self.ctx)
|
||||||
|
@ -1075,7 +1075,7 @@ async def process_client_cmd(ctx: Context, client: Client, cmd, args):
|
||||||
target_item, target_player = ctx.locations[(Regions.location_table[loc_name][0], client.slot)]
|
target_item, target_player = ctx.locations[(Regions.location_table[loc_name][0], client.slot)]
|
||||||
|
|
||||||
replacements = {'SmallKey': 0xA2, 'BigKey': 0x9D, 'Compass': 0x8D, 'Map': 0x7D}
|
replacements = {'SmallKey': 0xA2, 'BigKey': 0x9D, 'Compass': 0x8D, 'Map': 0x7D}
|
||||||
item_type = [i[2] for i in Items.item_table.values() if type(i[3]) is int and i[3] == target_item]
|
item_type = [i[1] for i in Items.item_table.values() if type(i[2]) is int and i[2] == target_item]
|
||||||
if item_type:
|
if item_type:
|
||||||
target_item = replacements.get(item_type[0], target_item)
|
target_item = replacements.get(item_type[0], target_item)
|
||||||
|
|
||||||
|
@ -1228,7 +1228,7 @@ class ServerCommandProcessor(CommonCommandProcessor):
|
||||||
if usable:
|
if usable:
|
||||||
for client in self.ctx.endpoints:
|
for client in self.ctx.endpoints:
|
||||||
if client.name == seeked_player:
|
if client.name == seeked_player:
|
||||||
new_item = ReceivedItem(Items.item_table[item][3], -1, client.slot)
|
new_item = ReceivedItem(Items.item_table[item][2], -1, client.slot)
|
||||||
get_received_items(self.ctx, client.team, client.slot).append(new_item)
|
get_received_items(self.ctx, client.team, client.slot).append(new_item)
|
||||||
self.ctx.notify_all('Cheat console: sending "' + item + '" to ' + self.ctx.get_aliased_name(client.team, client.slot))
|
self.ctx.notify_all('Cheat console: sending "' + item + '" to ' + self.ctx.get_aliased_name(client.team, client.slot))
|
||||||
send_new_items(self.ctx)
|
send_new_items(self.ctx)
|
||||||
|
|
69
Mystery.py
69
Mystery.py
|
@ -199,10 +199,10 @@ def main(args=None, callback=ERmain):
|
||||||
for option, player_settings in vars(erargs).items():
|
for option, player_settings in vars(erargs).items():
|
||||||
if type(player_settings) == dict:
|
if type(player_settings) == dict:
|
||||||
if all(type(value) != list for value in player_settings.values()):
|
if all(type(value) != list for value in player_settings.values()):
|
||||||
if len(frozenset(player_settings.values())) > 1:
|
if len(player_settings.values()) > 1:
|
||||||
important[option] = {player: value for player, value in player_settings.items() if
|
important[option] = {player: value for player, value in player_settings.items() if
|
||||||
player <= args.yaml_output}
|
player <= args.yaml_output}
|
||||||
elif len(frozenset(player_settings.values())) > 0:
|
elif len(player_settings.values()) > 0:
|
||||||
important[option] = player_settings[1]
|
important[option] = player_settings[1]
|
||||||
else:
|
else:
|
||||||
logging.debug(f"No player settings defined for option '{option}'")
|
logging.debug(f"No player settings defined for option '{option}'")
|
||||||
|
@ -291,10 +291,18 @@ def roll_percentage(percentage: typing.Union[int, float]) -> bool:
|
||||||
percentage is expected to be in range [0, 100]"""
|
percentage is expected to be in range [0, 100]"""
|
||||||
return random.random() < (float(percentage) / 100)
|
return random.random() < (float(percentage) / 100)
|
||||||
|
|
||||||
|
def update_weights(weights: dict, new_weights: dict, type: str, name: str) -> dict:
|
||||||
|
logging.debug(f'Applying {new_weights}')
|
||||||
|
new_options = set(new_weights) - set(weights)
|
||||||
|
weights.update(new_weights)
|
||||||
|
if new_options:
|
||||||
|
for new_option in new_options:
|
||||||
|
logging.warning(f'{type} Suboption "{new_option}" of "{name}" did not '
|
||||||
|
f'overwrite a root option. '
|
||||||
|
f'This is probably in error.')
|
||||||
|
return weights
|
||||||
|
|
||||||
def roll_settings(weights, plando_options: typing.Set[str] = frozenset(("bosses"))):
|
def roll_linked_options(weights: dict) -> dict:
|
||||||
ret = argparse.Namespace()
|
|
||||||
if "linked_options" in weights:
|
|
||||||
weights = weights.copy() # make sure we don't write back to other weights sets in same_settings
|
weights = weights.copy() # make sure we don't write back to other weights sets in same_settings
|
||||||
for option_set in weights["linked_options"]:
|
for option_set in weights["linked_options"]:
|
||||||
if "name" not in option_set:
|
if "name" not in option_set:
|
||||||
|
@ -302,20 +310,52 @@ def roll_settings(weights, plando_options: typing.Set[str] = frozenset(("bosses"
|
||||||
try:
|
try:
|
||||||
if roll_percentage(option_set["percentage"]):
|
if roll_percentage(option_set["percentage"]):
|
||||||
logging.debug(f"Linked option {option_set['name']} triggered.")
|
logging.debug(f"Linked option {option_set['name']} triggered.")
|
||||||
logging.debug(f'Applying {option_set["options"]}')
|
if "options" in option_set:
|
||||||
new_options = set(option_set["options"]) - set(weights)
|
weights = update_weights(weights, option_set["options"], "Linked", option_set["name"])
|
||||||
weights.update(option_set["options"])
|
if "rom_options" in option_set:
|
||||||
if new_options:
|
rom_weights = weights.get("rom", dict())
|
||||||
for new_option in new_options:
|
rom_weights = update_weights(rom_weights, option_set["rom_options"], "Linked Rom", option_set["name"])
|
||||||
logging.warning(f'Linked Suboption "{new_option}" of "{option_set["name"]}" did not '
|
weights["rom"] = rom_weights
|
||||||
f'overwrite a root option. '
|
|
||||||
f"This is probably in error.")
|
|
||||||
else:
|
else:
|
||||||
logging.debug(f"linked option {option_set['name']} skipped.")
|
logging.debug(f"linked option {option_set['name']} skipped.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(f"Linked option {option_set['name']} is destroyed. "
|
raise ValueError(f"Linked option {option_set['name']} is destroyed. "
|
||||||
f"Please fix your linked option.") from e
|
f"Please fix your linked option.") from e
|
||||||
|
return weights
|
||||||
|
|
||||||
|
def roll_triggers(weights: dict) -> dict:
|
||||||
|
weights = weights.copy() # make sure we don't write back to other weights sets in same_settings
|
||||||
|
weights["_Generator_Version"] = "Main" # Some means for triggers to know if the seed is on main or doors.
|
||||||
|
for option_set in weights["triggers"]:
|
||||||
|
try:
|
||||||
|
key = get_choice("option_name", option_set)
|
||||||
|
if key not in weights:
|
||||||
|
logging.warning(f'Specified option name {option_set["option_name"]} did not '
|
||||||
|
f'match with a root option. '
|
||||||
|
f'This is probably in error.')
|
||||||
|
trigger_result = get_choice("option_result", option_set)
|
||||||
|
result = get_choice(key, weights)
|
||||||
|
if result == trigger_result and roll_percentage(get_choice("percentage", option_set, 100)):
|
||||||
|
if "options" in option_set:
|
||||||
|
weights = update_weights(weights, option_set["options"], "Triggered", option_set["option_name"])
|
||||||
|
if "rom_options" in option_set:
|
||||||
|
rom_weights = weights.get("rom", dict())
|
||||||
|
rom_weights = update_weights(rom_weights, option_set["rom_options"], "Triggered Rom", option_set["option_name"])
|
||||||
|
weights["rom"] = rom_weights
|
||||||
|
weights[key] = result
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f"A trigger is destroyed. "
|
||||||
|
f"Please fix your triggers.") from e
|
||||||
|
return weights
|
||||||
|
|
||||||
|
def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("bosses"))):
|
||||||
|
if "linked_options" in weights:
|
||||||
|
weights = roll_linked_options(weights)
|
||||||
|
|
||||||
|
if "triggers" in weights:
|
||||||
|
weights = roll_triggers(weights)
|
||||||
|
|
||||||
|
ret = argparse.Namespace()
|
||||||
ret.name = get_choice('name', weights)
|
ret.name = get_choice('name', weights)
|
||||||
if ret.name:
|
if ret.name:
|
||||||
ret.name = handle_name(ret.name)
|
ret.name = handle_name(ret.name)
|
||||||
|
@ -379,7 +419,7 @@ def roll_settings(weights, plando_options: typing.Set[str] = frozenset(("bosses"
|
||||||
|
|
||||||
# TODO consider moving open_pyramid to an automatic variable in the core roller, set to True when
|
# TODO consider moving open_pyramid to an automatic variable in the core roller, set to True when
|
||||||
# fast ganon + ganon at hole
|
# fast ganon + ganon at hole
|
||||||
ret.open_pyramid = ret.goal in {'crystals', 'ganontriforcehunt', 'localganontriforcehunt', 'ganonpedestal'}
|
ret.open_pyramid = get_choice('open_pyramid', weights, 'goal')
|
||||||
|
|
||||||
ret.crystals_gt = prefer_int(get_choice('tower_open', weights))
|
ret.crystals_gt = prefer_int(get_choice('tower_open', weights))
|
||||||
|
|
||||||
|
@ -653,6 +693,7 @@ def roll_settings(weights, plando_options: typing.Set[str] = frozenset(("bosses"
|
||||||
ret.triforcehud = get_choice('triforcehud', romweights, 'hide_goal')
|
ret.triforcehud = get_choice('triforcehud', romweights, 'hide_goal')
|
||||||
ret.quickswap = get_choice('quickswap', romweights, True)
|
ret.quickswap = get_choice('quickswap', romweights, True)
|
||||||
ret.fastmenu = get_choice('menuspeed', romweights, "normal")
|
ret.fastmenu = get_choice('menuspeed', romweights, "normal")
|
||||||
|
ret.reduceflashing = get_choice('reduceflashing', romweights, False)
|
||||||
ret.heartcolor = get_choice('heartcolor', romweights, "red")
|
ret.heartcolor = get_choice('heartcolor', romweights, "red")
|
||||||
ret.heartbeep = convert_to_on_off(get_choice('heartbeep', romweights, "normal"))
|
ret.heartbeep = convert_to_on_off(get_choice('heartbeep', romweights, "normal"))
|
||||||
ret.ow_palettes = get_choice('ow_palettes', romweights, "default")
|
ret.ow_palettes = get_choice('ow_palettes', romweights, "default")
|
||||||
|
|
|
@ -9,7 +9,8 @@ def create_regions(world, player):
|
||||||
|
|
||||||
world.regions += [
|
world.regions += [
|
||||||
create_lw_region(player, 'Menu', None, ['Links House S&Q', 'Sanctuary S&Q', 'Old Man S&Q']),
|
create_lw_region(player, 'Menu', None, ['Links House S&Q', 'Sanctuary S&Q', 'Old Man S&Q']),
|
||||||
create_lw_region(player, 'Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure', 'Purple Chest'],
|
create_lw_region(player, 'Light World', ['Mushroom', 'Bottle Merchant', 'Flute Spot', 'Sunken Treasure',
|
||||||
|
'Purple Chest', 'Flute Activation Spot'],
|
||||||
["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Zoras River', 'Kings Grave Outer Rocks', 'Dam',
|
["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Zoras River', 'Kings Grave Outer Rocks', 'Dam',
|
||||||
'Links House', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave',
|
'Links House', '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',
|
'Blacksmiths Hut', 'Bat Cave Drop Ledge', 'Bat Cave Cave', 'Sick Kids House', 'Hobo Bridge', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump',
|
||||||
|
@ -653,6 +654,7 @@ location_table: typing.Dict[str,
|
||||||
'Frog': (None, None, False, None),
|
'Frog': (None, None, False, None),
|
||||||
'Missing Smith': (None, None, False, None),
|
'Missing Smith': (None, None, False, None),
|
||||||
'Dark Blacksmith Ruins': (None, None, False, None),
|
'Dark Blacksmith Ruins': (None, None, False, None),
|
||||||
|
'Flute Activation Spot': (None, None, False, None),
|
||||||
'Eastern Palace - Prize': ([0x1209D, 0x53EF8, 0x53EF9, 0x180052, 0x18007C, 0xC6FE], None, True, 'Eastern Palace'),
|
'Eastern Palace - Prize': ([0x1209D, 0x53EF8, 0x53EF9, 0x180052, 0x18007C, 0xC6FE], None, True, 'Eastern Palace'),
|
||||||
'Desert Palace - Prize': ([0x1209E, 0x53F1C, 0x53F1D, 0x180053, 0x180078, 0xC6FF], None, True, 'Desert Palace'),
|
'Desert Palace - Prize': ([0x1209E, 0x53F1C, 0x53F1D, 0x180053, 0x180078, 0xC6FF], None, True, 'Desert Palace'),
|
||||||
'Tower of Hera - Prize': (
|
'Tower of Hera - Prize': (
|
||||||
|
|
172
Rom.py
172
Rom.py
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = '9cbbc0876dd5748125eda8b315347ad2'
|
RANDOMIZERBASEHASH = 'a0a9511a2a59e5e8009b38718f8da1bf'
|
||||||
|
|
||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
|
@ -18,7 +18,7 @@ import concurrent.futures
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from BaseClasses import CollectionState, Region, Location
|
from BaseClasses import CollectionState, Region, Location
|
||||||
from Shops import ShopType
|
from Shops import ShopType, total_shop_slots
|
||||||
from Dungeons import dungeon_music_addresses
|
from Dungeons import dungeon_music_addresses
|
||||||
from Regions import location_table, old_location_address_to_new_location_address
|
from Regions import location_table, old_location_address_to_new_location_address
|
||||||
from Text import MultiByteTextMapper, CompressedTextMapper, text_addresses, Credits, TextTable
|
from Text import MultiByteTextMapper, CompressedTextMapper, text_addresses, Credits, TextTable
|
||||||
|
@ -674,6 +674,14 @@ class Sprite(object):
|
||||||
rom.write_bytes(0x307000, self.palette)
|
rom.write_bytes(0x307000, self.palette)
|
||||||
rom.write_bytes(0x307078, self.glove_palette)
|
rom.write_bytes(0x307078, self.glove_palette)
|
||||||
|
|
||||||
|
bonk_addresses = [0x4CF6C, 0x4CFBA, 0x4CFE0, 0x4CFFB, 0x4D018, 0x4D01B, 0x4D028, 0x4D03C, 0x4D059, 0x4D07A,
|
||||||
|
0x4D09E, 0x4D0A8, 0x4D0AB, 0x4D0AE, 0x4D0BE, 0x4D0DD,
|
||||||
|
0x4D16A, 0x4D1E5, 0x4D1EE, 0x4D20B, 0x4CBBF, 0x4CBBF, 0x4CC17, 0x4CC1A, 0x4CC4A, 0x4CC4D,
|
||||||
|
0x4CC53, 0x4CC69, 0x4CC6F, 0x4CC7C, 0x4CCEF, 0x4CD51,
|
||||||
|
0x4CDC0, 0x4CDC3, 0x4CDC6, 0x4CE37, 0x4D2DE, 0x4D32F, 0x4D355, 0x4D367, 0x4D384, 0x4D387,
|
||||||
|
0x4D397, 0x4D39E, 0x4D3AB, 0x4D3AE, 0x4D3D1, 0x4D3D7,
|
||||||
|
0x4D3F8, 0x4D416, 0x4D420, 0x4D423, 0x4D42D, 0x4D449, 0x4D48C, 0x4D4D9, 0x4D4DC, 0x4D4E3,
|
||||||
|
0x4D504, 0x4D507, 0x4D55E, 0x4D56A]
|
||||||
|
|
||||||
def patch_rom(world, rom, player, team, enemized):
|
def patch_rom(world, rom, player, team, enemized):
|
||||||
local_random = world.rom_seeds[player]
|
local_random = world.rom_seeds[player]
|
||||||
|
@ -791,6 +799,27 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
|
|
||||||
write_custom_shops(rom, world, player)
|
write_custom_shops(rom, world, player)
|
||||||
|
|
||||||
|
def credits_digit(num):
|
||||||
|
# top: $54 is 1, 55 2, etc , so 57=4, 5C=9
|
||||||
|
# bot: $7A is 1, 7B is 2, etc so 7D=4, 82=9 (zero unknown...)
|
||||||
|
return 0x53 + int(num), 0x79 + int(num)
|
||||||
|
|
||||||
|
credits_total = 216
|
||||||
|
if world.retro[player]: # Old man cave and Take any caves will count towards collection rate.
|
||||||
|
credits_total += 5
|
||||||
|
if world.shop_shuffle_slots[player]: # Potion shop only counts towards collection rate if included in the shuffle.
|
||||||
|
credits_total += 30 if 'w' in world.shop_shuffle[player] else 27
|
||||||
|
|
||||||
|
rom.write_byte(0x187010, credits_total) # dynamic credits
|
||||||
|
# collection rate address: 238C37
|
||||||
|
first_top, first_bot = credits_digit((credits_total / 100) % 10)
|
||||||
|
mid_top, mid_bot = credits_digit((credits_total / 10) % 10)
|
||||||
|
last_top, last_bot = credits_digit(credits_total % 10)
|
||||||
|
# top half
|
||||||
|
rom.write_bytes(0x118C46, [first_top, mid_top, last_top])
|
||||||
|
# bottom half
|
||||||
|
rom.write_bytes(0x118C64, [first_bot, mid_bot, last_bot])
|
||||||
|
|
||||||
# patch medallion requirements
|
# patch medallion requirements
|
||||||
if world.required_medallions[player][0] == 'Bombos':
|
if world.required_medallions[player][0] == 'Bombos':
|
||||||
rom.write_byte(0x180022, 0x00) # requirement
|
rom.write_byte(0x180022, 0x00) # requirement
|
||||||
|
@ -847,8 +876,8 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
|
|
||||||
rom.write_byte(0x18004F, 0x01) # Byrna Invulnerability: on
|
rom.write_byte(0x18004F, 0x01) # Byrna Invulnerability: on
|
||||||
|
|
||||||
# handle difficulty_adjustments
|
# handle item_functionality
|
||||||
if world.difficulty_adjustments[player] == 'hard':
|
if world.item_functionality[player] == 'hard':
|
||||||
rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon
|
rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon
|
||||||
rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup
|
rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup
|
||||||
# Powdered Fairies Prize
|
# Powdered Fairies Prize
|
||||||
|
@ -868,7 +897,7 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
rom.write_int16(0x180036, world.rupoor_cost)
|
rom.write_int16(0x180036, world.rupoor_cost)
|
||||||
# Set stun items
|
# Set stun items
|
||||||
rom.write_byte(0x180180, 0x02) # Hookshot only
|
rom.write_byte(0x180180, 0x02) # Hookshot only
|
||||||
elif world.difficulty_adjustments[player] == 'expert':
|
elif world.item_functionality[player] == 'expert':
|
||||||
rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon
|
rom.write_byte(0x180181, 0x01) # Make silver arrows work only on ganon
|
||||||
rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup
|
rom.write_byte(0x180182, 0x00) # Don't auto equip silvers on pickup
|
||||||
# Powdered Fairies Prize
|
# Powdered Fairies Prize
|
||||||
|
@ -937,6 +966,15 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
|
|
||||||
# set up game internal RNG seed
|
# set up game internal RNG seed
|
||||||
rom.write_bytes(0x178000, local_random.getrandbits(8 * 1024).to_bytes(1024, 'big'))
|
rom.write_bytes(0x178000, local_random.getrandbits(8 * 1024).to_bytes(1024, 'big'))
|
||||||
|
prize_replacements = {}
|
||||||
|
if world.item_functionality[player] in ['hard', 'expert']:
|
||||||
|
prize_replacements[0xE0] = 0xDF # Fairy -> heart
|
||||||
|
prize_replacements[0xE3] = 0xD8 # Big magic -> small magic
|
||||||
|
|
||||||
|
if world.retro[player]:
|
||||||
|
prize_replacements[0xE1] = 0xDA # 5 Arrows -> Blue Rupee
|
||||||
|
prize_replacements[0xE2] = 0xDB # 10 Arrows -> Red Rupee
|
||||||
|
|
||||||
if "g" in world.shuffle_prizes[player]:
|
if "g" in world.shuffle_prizes[player]:
|
||||||
# shuffle prize packs
|
# shuffle prize packs
|
||||||
prizes = [0xD8, 0xD8, 0xD8, 0xD8, 0xD9, 0xD8, 0xD8, 0xD9, 0xDA, 0xD9, 0xDA, 0xDB, 0xDA, 0xD9, 0xDA, 0xDA, 0xE0,
|
prizes = [0xD8, 0xD8, 0xD8, 0xD8, 0xD9, 0xD8, 0xD8, 0xD9, 0xDA, 0xD9, 0xDA, 0xDB, 0xDA, 0xD9, 0xDA, 0xDA, 0xE0,
|
||||||
|
@ -962,18 +1000,10 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
packs = chunk(prizes[:56], 8)
|
packs = chunk(prizes[:56], 8)
|
||||||
local_random.shuffle(packs)
|
local_random.shuffle(packs)
|
||||||
prizes[:56] = [drop for pack in packs for drop in pack]
|
prizes[:56] = [drop for pack in packs for drop in pack]
|
||||||
|
if prize_replacements:
|
||||||
if world.difficulty_adjustments[player] in ['hard', 'expert']:
|
|
||||||
prize_replacements = {0xE0: 0xDF, # Fairy -> heart
|
|
||||||
0xE3: 0xD8} # Big magic -> small magic
|
|
||||||
prizes = [prize_replacements.get(prize, prize) for prize in prizes]
|
prizes = [prize_replacements.get(prize, prize) for prize in prizes]
|
||||||
dig_prizes = [prize_replacements.get(prize, prize) for prize in dig_prizes]
|
dig_prizes = [prize_replacements.get(prize, prize) for prize in dig_prizes]
|
||||||
|
|
||||||
if world.retro[player]:
|
|
||||||
prize_replacements = {0xE1: 0xDA, # 5 Arrows -> Blue Rupee
|
|
||||||
0xE2: 0xDB} # 10 Arrows -> Red Rupee
|
|
||||||
prizes = [prize_replacements.get(prize, prize) for prize in prizes]
|
|
||||||
dig_prizes = [prize_replacements.get(prize, prize) for prize in dig_prizes]
|
|
||||||
rom.write_bytes(0x180100, dig_prizes)
|
rom.write_bytes(0x180100, dig_prizes)
|
||||||
|
|
||||||
# write tree pull prizes
|
# write tree pull prizes
|
||||||
|
@ -994,6 +1024,19 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
# fill enemy prize packs
|
# fill enemy prize packs
|
||||||
rom.write_bytes(0x37A78, prizes)
|
rom.write_bytes(0x37A78, prizes)
|
||||||
|
|
||||||
|
elif prize_replacements:
|
||||||
|
dig_prizes = list(rom.read_bytes(0x180100, 64))
|
||||||
|
dig_prizes = [prize_replacements.get(byte, byte) for byte in dig_prizes]
|
||||||
|
rom.write_bytes(0x180100, dig_prizes)
|
||||||
|
|
||||||
|
prizes = list(rom.read_bytes(0x37A78, 56))
|
||||||
|
prizes = [prize_replacements.get(byte, byte) for byte in prizes]
|
||||||
|
rom.write_bytes(0x37A78, prizes)
|
||||||
|
|
||||||
|
for address in (0xEFBD4, 0xEFBD5, 0xEFBD6, 0x329C8, 0x329C4, 0x37993, 0xE82CC):
|
||||||
|
byte = int(rom.read_byte(address))
|
||||||
|
rom.write_byte(address, prize_replacements.get(byte, byte))
|
||||||
|
|
||||||
if "b" in world.shuffle_prizes[player]:
|
if "b" in world.shuffle_prizes[player]:
|
||||||
# set bonk prizes
|
# set bonk prizes
|
||||||
bonk_prizes = [0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xAC, 0xE3, 0xE3, 0xDA, 0xE3, 0xDA, 0xD8, 0xAC,
|
bonk_prizes = [0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xAC, 0xE3, 0xE3, 0xDA, 0xE3, 0xDA, 0xD8, 0xAC,
|
||||||
|
@ -1001,18 +1044,21 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
0xE3, 0xE3,
|
0xE3, 0xE3,
|
||||||
0xDA, 0x79, 0xAC, 0xAC, 0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xE3, 0x79, 0xDE, 0xE3,
|
0xDA, 0x79, 0xAC, 0xAC, 0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xE3, 0x79, 0xDE, 0xE3,
|
||||||
0xAC, 0xDB, 0x79, 0xE3, 0xD8, 0xAC, 0x79, 0xE3, 0xDB, 0xDB, 0xE3, 0xE3, 0x79, 0xD8, 0xDD]
|
0xAC, 0xDB, 0x79, 0xE3, 0xD8, 0xAC, 0x79, 0xE3, 0xDB, 0xDB, 0xE3, 0xE3, 0x79, 0xD8, 0xDD]
|
||||||
bonk_addresses = [0x4CF6C, 0x4CFBA, 0x4CFE0, 0x4CFFB, 0x4D018, 0x4D01B, 0x4D028, 0x4D03C, 0x4D059, 0x4D07A,
|
|
||||||
0x4D09E, 0x4D0A8, 0x4D0AB, 0x4D0AE, 0x4D0BE, 0x4D0DD,
|
|
||||||
0x4D16A, 0x4D1E5, 0x4D1EE, 0x4D20B, 0x4CBBF, 0x4CBBF, 0x4CC17, 0x4CC1A, 0x4CC4A, 0x4CC4D,
|
|
||||||
0x4CC53, 0x4CC69, 0x4CC6F, 0x4CC7C, 0x4CCEF, 0x4CD51,
|
|
||||||
0x4CDC0, 0x4CDC3, 0x4CDC6, 0x4CE37, 0x4D2DE, 0x4D32F, 0x4D355, 0x4D367, 0x4D384, 0x4D387,
|
|
||||||
0x4D397, 0x4D39E, 0x4D3AB, 0x4D3AE, 0x4D3D1, 0x4D3D7,
|
|
||||||
0x4D3F8, 0x4D416, 0x4D420, 0x4D423, 0x4D42D, 0x4D449, 0x4D48C, 0x4D4D9, 0x4D4DC, 0x4D4E3,
|
|
||||||
0x4D504, 0x4D507, 0x4D55E, 0x4D56A]
|
|
||||||
local_random.shuffle(bonk_prizes)
|
local_random.shuffle(bonk_prizes)
|
||||||
|
|
||||||
|
if prize_replacements:
|
||||||
|
bonk_prizes = [prize_replacements.get(prize, prize) for prize in bonk_prizes]
|
||||||
|
|
||||||
for prize, address in zip(bonk_prizes, bonk_addresses):
|
for prize, address in zip(bonk_prizes, bonk_addresses):
|
||||||
rom.write_byte(address, prize)
|
rom.write_byte(address, prize)
|
||||||
|
|
||||||
|
elif prize_replacements:
|
||||||
|
for address in bonk_addresses:
|
||||||
|
byte = int(rom.read_byte(address))
|
||||||
|
rom.write_byte(address, prize_replacements.get(byte, byte))
|
||||||
|
|
||||||
|
|
||||||
# Fill in item substitutions table
|
# Fill in item substitutions table
|
||||||
rom.write_bytes(0x184000, [
|
rom.write_bytes(0x184000, [
|
||||||
# original_item, limit, replacement_item, filler
|
# original_item, limit, replacement_item, filler
|
||||||
|
@ -1071,7 +1117,7 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
rom.write_byte(0x180043, 0xFF if world.swords[player] == 'swordless' else 0x00) # starting sword for link
|
rom.write_byte(0x180043, 0xFF if world.swords[player] == 'swordless' else 0x00) # starting sword for link
|
||||||
rom.write_byte(0x180044, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer activates tablets
|
rom.write_byte(0x180044, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer activates tablets
|
||||||
|
|
||||||
if world.difficulty_adjustments[player] == 'easy':
|
if world.item_functionality[player] == 'easy':
|
||||||
rom.write_byte(0x18003F, 0x01) # hammer can harm ganon
|
rom.write_byte(0x18003F, 0x01) # hammer can harm ganon
|
||||||
rom.write_byte(0x180041, 0x02) # Allow swordless medallion use EVERYWHERE.
|
rom.write_byte(0x180041, 0x02) # Allow swordless medallion use EVERYWHERE.
|
||||||
rom.write_byte(0x180044, 0x01) # hammer activates tablets
|
rom.write_byte(0x180044, 0x01) # hammer activates tablets
|
||||||
|
@ -1250,7 +1296,9 @@ def patch_rom(world, rom, player, team, enemized):
|
||||||
'Big Key (Ganons Tower)': (0x366, 0x04), 'Compass (Ganons Tower)': (0x364, 0x04),
|
'Big Key (Ganons Tower)': (0x366, 0x04), 'Compass (Ganons Tower)': (0x364, 0x04),
|
||||||
'Map (Ganons Tower)': (0x368, 0x04)}
|
'Map (Ganons Tower)': (0x368, 0x04)}
|
||||||
set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02), 'Pegasus Boots': (0x355, 1, 0x379, 0x04),
|
set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02), 'Pegasus Boots': (0x355, 1, 0x379, 0x04),
|
||||||
'Shovel': (0x34C, 1, 0x38C, 0x04), 'Flute': (0x34C, 3, 0x38C, 0x01),
|
'Shovel': (0x34C, 1, 0x38C, 0x04),
|
||||||
|
'Flute': (0x34C, 2, 0x38C, 0x02),
|
||||||
|
'Activated Flute': (0x34C, 3, 0x38C, 0x01),
|
||||||
'Mushroom': (0x344, 1, 0x38C, 0x20 | 0x08), 'Magic Powder': (0x344, 2, 0x38C, 0x10),
|
'Mushroom': (0x344, 1, 0x38C, 0x20 | 0x08), 'Magic Powder': (0x344, 2, 0x38C, 0x10),
|
||||||
'Blue Boomerang': (0x341, 1, 0x38C, 0x80), 'Red Boomerang': (0x341, 2, 0x38C, 0x40)}
|
'Blue Boomerang': (0x341, 1, 0x38C, 0x80), 'Red Boomerang': (0x341, 2, 0x38C, 0x40)}
|
||||||
keys = {'Small Key (Eastern Palace)': [0x37E], 'Small Key (Desert Palace)': [0x37F],
|
keys = {'Small Key (Eastern Palace)': [0x37E], 'Small Key (Desert Palace)': [0x37F],
|
||||||
|
@ -1560,6 +1608,7 @@ def write_custom_shops(rom, world, player):
|
||||||
|
|
||||||
shop_data = bytearray()
|
shop_data = bytearray()
|
||||||
items_data = bytearray()
|
items_data = bytearray()
|
||||||
|
retro_shop_slots = bytearray()
|
||||||
|
|
||||||
for shop_id, shop in enumerate(shops):
|
for shop_id, shop in enumerate(shops):
|
||||||
if shop_id == len(shops) - 1:
|
if shop_id == len(shops) - 1:
|
||||||
|
@ -1568,10 +1617,27 @@ def write_custom_shops(rom, world, player):
|
||||||
bytes[0] = shop_id
|
bytes[0] = shop_id
|
||||||
bytes[-1] = shop.sram_offset
|
bytes[-1] = shop.sram_offset
|
||||||
shop_data.extend(bytes)
|
shop_data.extend(bytes)
|
||||||
# [id][item][price-low][price-high][max][repl_id][repl_price-low][repl_price-high][player]
|
|
||||||
for item in shop.inventory:
|
arrow_mask = 0x00
|
||||||
|
for index, item in enumerate(shop.inventory):
|
||||||
|
slot = 0 if shop.type == ShopType.TakeAny else index
|
||||||
if item is None:
|
if item is None:
|
||||||
break
|
break
|
||||||
|
if world.shop_shuffle_slots[player] or shop.type == ShopType.TakeAny:
|
||||||
|
count_shop = (shop.region.name != 'Potion Shop' or 'w' in world.shop_shuffle[player]) and \
|
||||||
|
shop.region.name != 'Capacity Upgrade'
|
||||||
|
rom.write_byte(0x186560 + shop.sram_offset + slot, 1 if count_shop else 0)
|
||||||
|
if item['item'] == 'Single Arrow' and item['player'] == 0:
|
||||||
|
arrow_mask |= 1 << index
|
||||||
|
retro_shop_slots.append(shop.sram_offset + slot)
|
||||||
|
|
||||||
|
# [id][item][price-low][price-high][max][repl_id][repl_price-low][repl_price-high][player]
|
||||||
|
for index, item in enumerate(shop.inventory):
|
||||||
|
slot = 0 if shop.type == ShopType.TakeAny else index
|
||||||
|
if item is None:
|
||||||
|
break
|
||||||
|
if item['item'] == 'Single Arrow' and item['player'] == 0 and world.retro[player]:
|
||||||
|
rom.write_byte(0x186500 + shop.sram_offset + slot, arrow_mask)
|
||||||
item_data = [shop_id, ItemFactory(item['item'], player).code] + int16_as_bytes(item['price']) + \
|
item_data = [shop_id, ItemFactory(item['item'], player).code] + int16_as_bytes(item['price']) + \
|
||||||
[item['max'], ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF] + \
|
[item['max'], ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF] + \
|
||||||
int16_as_bytes(item['replacement_price']) + [0 if item['player'] == player else item['player']]
|
int16_as_bytes(item['replacement_price']) + [0 if item['player'] == player else item['player']]
|
||||||
|
@ -1582,6 +1648,10 @@ def write_custom_shops(rom, world, player):
|
||||||
items_data.extend([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
|
items_data.extend([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
|
||||||
rom.write_bytes(0x184900, items_data)
|
rom.write_bytes(0x184900, items_data)
|
||||||
|
|
||||||
|
if world.retro[player]:
|
||||||
|
retro_shop_slots.append(0xFF)
|
||||||
|
rom.write_bytes(0x186540, retro_shop_slots)
|
||||||
|
|
||||||
|
|
||||||
def hud_format_text(text):
|
def hud_format_text(text):
|
||||||
output = bytes()
|
output = bytes()
|
||||||
|
@ -1602,7 +1672,7 @@ def hud_format_text(text):
|
||||||
|
|
||||||
|
|
||||||
def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, triforcehud, sprite: str, palettes_options,
|
def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, triforcehud, sprite: str, palettes_options,
|
||||||
world=None, player=1, allow_random_on_event=False):
|
world=None, player=1, allow_random_on_event=False, reduceflashing=False):
|
||||||
local_random = random if not world else world.rom_seeds[player]
|
local_random = random if not world else world.rom_seeds[player]
|
||||||
|
|
||||||
# enable instant item menu
|
# enable instant item menu
|
||||||
|
@ -1627,6 +1697,23 @@ def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, tri
|
||||||
else:
|
else:
|
||||||
rom.write_byte(0x180048, 0x08)
|
rom.write_byte(0x180048, 0x08)
|
||||||
|
|
||||||
|
|
||||||
|
# Reduce flashing by nopping out instructions
|
||||||
|
if reduceflashing:
|
||||||
|
rom.write_bytes(0x17E07, [0x06]) # reduce amount of colors changed, add this branch if we need to reduce more ""+ [0x80] + [(0x81-0x08)]""
|
||||||
|
rom.write_bytes(0x17EAB, [0xD0, 0x03, 0xA9, 0x40, 0x29, 0x60]) # nullifies aga lightning, cutscene, vitreous, bat, ether
|
||||||
|
# ONLY write to black values with this low pale blue to indicate flashing, that's IT. ""BNE + : LDA #$2940 : + : RTS""
|
||||||
|
rom.write_bytes(0x123FE, [0x72]) # set lightning flash in misery mire (and standard) to brightness 0x72
|
||||||
|
rom.write_bytes(0x3FA7B, [0x80, 0xac-0x7b]) # branch from palette writing lightning on death mountain
|
||||||
|
rom.write_byte(0x10817F, 0x01) # internal rom option
|
||||||
|
else:
|
||||||
|
rom.write_bytes(0x17E07, [0x00])
|
||||||
|
rom.write_bytes(0x17EAB, [0x85, 0x00, 0x29, 0x1F, 0x00, 0x18])
|
||||||
|
rom.write_bytes(0x123FE, [0x32]) # original weather flash value
|
||||||
|
rom.write_bytes(0x3FA7B, [0xc2, 0x20]) # rep #$20
|
||||||
|
rom.write_byte(0x10817F, 0x00) # internal rom option
|
||||||
|
|
||||||
|
|
||||||
rom.write_byte(0x18004B, 0x01 if quickswap else 0x00)
|
rom.write_byte(0x18004B, 0x01 if quickswap else 0x00)
|
||||||
|
|
||||||
rom.write_byte(0x0CFE18, 0x00 if disable_music else rom.orig_buffer[0x0CFE18] if rom.orig_buffer else 0x70)
|
rom.write_byte(0x0CFE18, 0x00 if disable_music else rom.orig_buffer[0x0CFE18] if rom.orig_buffer else 0x70)
|
||||||
|
@ -1911,6 +1998,9 @@ def write_strings(rom, world, player, team):
|
||||||
tt['kakariko_flophouse_man_no_flippers'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.'
|
tt['kakariko_flophouse_man_no_flippers'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.'
|
||||||
tt['kakariko_flophouse_man'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.'
|
tt['kakariko_flophouse_man'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.'
|
||||||
|
|
||||||
|
if world.mode[player] == 'inverted':
|
||||||
|
tt['sign_village_of_outcasts'] = 'attention\nferal ducks sighted\nhiding in statues\n\nflute players beware\n'
|
||||||
|
|
||||||
def hint_text(dest, ped_hint=False):
|
def hint_text(dest, ped_hint=False):
|
||||||
if not dest:
|
if not dest:
|
||||||
return "nothing"
|
return "nothing"
|
||||||
|
@ -1929,6 +2019,15 @@ def write_strings(rom, world, player, team):
|
||||||
|
|
||||||
# For hints, first we write hints about entrances, some from the inconvenient list others from all reasonable entrances.
|
# For hints, first we write hints about entrances, some from the inconvenient list others from all reasonable entrances.
|
||||||
if world.hints[player]:
|
if world.hints[player]:
|
||||||
|
# Zora hint
|
||||||
|
zora_location = world.get_location("King Zora", player)
|
||||||
|
tt['zora_tells_cost'] = f"You got 500 rupees to buy {hint_text(zora_location.item)}" \
|
||||||
|
f"\n ≥ Duh\n Oh carp\n{{CHOICE}}"
|
||||||
|
# Bottle Vendor hint
|
||||||
|
vendor_location = world.get_location("Bottle Merchant", player)
|
||||||
|
tt['bottle_vendor_choice'] = f"I gots {hint_text(vendor_location.item)}\nYous gots 100 rupees?"\
|
||||||
|
f"\n ≥ I want\n no way!\n{{CHOICE}}"
|
||||||
|
|
||||||
tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles can have hints!'
|
tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles can have hints!'
|
||||||
hint_locations = HintLocations.copy()
|
hint_locations = HintLocations.copy()
|
||||||
local_random.shuffle(hint_locations)
|
local_random.shuffle(hint_locations)
|
||||||
|
@ -1961,7 +2060,7 @@ def write_strings(rom, world, player, team):
|
||||||
hint_count = 4
|
hint_count = 4
|
||||||
for entrance in all_entrances:
|
for entrance in all_entrances:
|
||||||
if entrance.name in entrances_to_hint:
|
if entrance.name in entrances_to_hint:
|
||||||
if hint_count > 0:
|
if hint_count:
|
||||||
this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(
|
this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(
|
||||||
entrance.connected_region) + '.'
|
entrance.connected_region) + '.'
|
||||||
tt[hint_locations.pop(0)] = this_hint
|
tt[hint_locations.pop(0)] = this_hint
|
||||||
|
@ -1998,7 +2097,7 @@ def write_strings(rom, world, player, team):
|
||||||
hint_count = 4 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 0
|
hint_count = 4 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 0
|
||||||
for entrance in all_entrances:
|
for entrance in all_entrances:
|
||||||
if entrance.name in entrances_to_hint:
|
if entrance.name in entrances_to_hint:
|
||||||
if hint_count > 0:
|
if hint_count:
|
||||||
this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(
|
this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(
|
||||||
entrance.connected_region) + '.'
|
entrance.connected_region) + '.'
|
||||||
tt[hint_locations.pop(0)] = this_hint
|
tt[hint_locations.pop(0)] = this_hint
|
||||||
|
@ -2013,10 +2112,9 @@ def write_strings(rom, world, player, team):
|
||||||
locations_to_hint.extend(InconvenientVanillaLocations)
|
locations_to_hint.extend(InconvenientVanillaLocations)
|
||||||
local_random.shuffle(locations_to_hint)
|
local_random.shuffle(locations_to_hint)
|
||||||
hint_count = 3 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 5
|
hint_count = 3 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 5
|
||||||
del locations_to_hint[hint_count:]
|
for location in locations_to_hint[:hint_count]:
|
||||||
for location in locations_to_hint:
|
|
||||||
if location == 'Swamp Left':
|
if location == 'Swamp Left':
|
||||||
if local_random.randint(0, 1) == 0:
|
if local_random.randint(0, 1):
|
||||||
first_item = hint_text(world.get_location('Swamp Palace - West Chest', player).item)
|
first_item = hint_text(world.get_location('Swamp Palace - West Chest', player).item)
|
||||||
second_item = hint_text(world.get_location('Swamp Palace - Big Key Chest', player).item)
|
second_item = hint_text(world.get_location('Swamp Palace - Big Key Chest', player).item)
|
||||||
else:
|
else:
|
||||||
|
@ -2025,7 +2123,7 @@ def write_strings(rom, world, player, team):
|
||||||
this_hint = ('The westmost chests in Swamp Palace contain ' + first_item + ' and ' + second_item + '.')
|
this_hint = ('The westmost chests in Swamp Palace contain ' + first_item + ' and ' + second_item + '.')
|
||||||
tt[hint_locations.pop(0)] = this_hint
|
tt[hint_locations.pop(0)] = this_hint
|
||||||
elif location == 'Mire Left':
|
elif location == 'Mire Left':
|
||||||
if local_random.randint(0, 1) == 0:
|
if local_random.randint(0, 1):
|
||||||
first_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item)
|
first_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item)
|
||||||
second_item = hint_text(world.get_location('Misery Mire - Big Key Chest', player).item)
|
second_item = hint_text(world.get_location('Misery Mire - Big Key Chest', player).item)
|
||||||
else:
|
else:
|
||||||
|
@ -2085,8 +2183,8 @@ def write_strings(rom, world, player, team):
|
||||||
# All remaining hint slots are filled with junk hints. It is done this way to ensure the same junk hint isn't selected twice.
|
# All remaining hint slots are filled with junk hints. It is done this way to ensure the same junk hint isn't selected twice.
|
||||||
junk_hints = junk_texts.copy()
|
junk_hints = junk_texts.copy()
|
||||||
local_random.shuffle(junk_hints)
|
local_random.shuffle(junk_hints)
|
||||||
for location in hint_locations:
|
for location, text in zip(hint_locations, junk_hints):
|
||||||
tt[location] = junk_hints.pop(0)
|
tt[location] = text
|
||||||
|
|
||||||
# We still need the older hints of course. Those are done here.
|
# We still need the older hints of course. Those are done here.
|
||||||
|
|
||||||
|
@ -2273,6 +2371,10 @@ def set_inverted_mode(world, player, rom):
|
||||||
rom.write_byte(snes_to_pc(0x05AF79), 0xF0)
|
rom.write_byte(snes_to_pc(0x05AF79), 0xF0)
|
||||||
rom.write_byte(snes_to_pc(0x0DB3C5), 0xC6)
|
rom.write_byte(snes_to_pc(0x0DB3C5), 0xC6)
|
||||||
rom.write_byte(snes_to_pc(0x07A3F4), 0xF0) # duck
|
rom.write_byte(snes_to_pc(0x07A3F4), 0xF0) # duck
|
||||||
|
rom.write_byte(0xDC21D, 0x6B) # inverted mode flute activation (skip weathervane overlay)
|
||||||
|
rom.write_bytes(0x48DB3, [0xF8, 0x01]) # inverted mode (bird X)
|
||||||
|
rom.write_byte(0x48D5E, 0x01) # inverted mode (rock X)
|
||||||
|
rom.write_bytes(0x48CC1+36, bytes([0xF8]*12)) # (rock X)
|
||||||
rom.write_int16s(snes_to_pc(0x02E849),
|
rom.write_int16s(snes_to_pc(0x02E849),
|
||||||
[0x0043, 0x0056, 0x0058, 0x006C, 0x006F, 0x0070, 0x007B, 0x007F, 0x001B]) # dw flute
|
[0x0043, 0x0056, 0x0058, 0x006C, 0x006F, 0x0070, 0x007B, 0x007F, 0x001B]) # dw flute
|
||||||
rom.write_int16(snes_to_pc(0x02E8D5), 0x07C8)
|
rom.write_int16(snes_to_pc(0x02E8D5), 0x07C8)
|
||||||
|
|
80
Rules.py
80
Rules.py
|
@ -429,6 +429,8 @@ def global_rules(world, player):
|
||||||
add_rule(ganon, lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player))
|
add_rule(ganon, lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player))
|
||||||
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
|
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
|
||||||
|
|
||||||
|
set_rule(world.get_location('Flute Activation Spot', player), lambda state: state.has('Flute', player))
|
||||||
|
|
||||||
|
|
||||||
def default_rules(world, player):
|
def default_rules(world, player):
|
||||||
"""Default world rules when world state is not inverted."""
|
"""Default world rules when world state is not inverted."""
|
||||||
|
@ -447,9 +449,9 @@ def default_rules(world, player):
|
||||||
set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: state.can_lift_rocks(player))
|
||||||
set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: state.can_lift_rocks(player))
|
||||||
set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Activated Flute', player) and state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) # bunny cannot lift bushes
|
set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) # bunny cannot lift bushes
|
||||||
|
@ -575,7 +577,7 @@ def inverted_rules(world, player):
|
||||||
set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Dark Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player))
|
set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Activated Flute', player) and state.can_lift_heavy_rocks(player))
|
||||||
set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||||
set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player))
|
set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player))
|
||||||
|
@ -676,16 +678,16 @@ def inverted_rules(world, player):
|
||||||
|
|
||||||
# inverted flute spots
|
# inverted flute spots
|
||||||
|
|
||||||
set_rule(world.get_entrance('DDM Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('DDM Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('NEDW Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('NEDW Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('WDW Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('WDW Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('SDW Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('SDW Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('EDW Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('EDW Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('DLHL Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('DLHL Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('DD Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('DD Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('EDDM Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('EDDM Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.can_flute(player))
|
set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.has('Activated Flute', player))
|
||||||
|
|
||||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
|
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
|
||||||
|
|
||||||
|
@ -1125,52 +1127,52 @@ def set_big_bomb_rules(world, player):
|
||||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||||
# 1. mirror then flute then basic routes
|
# 1. mirror then flute then basic routes
|
||||||
# -> M and Flute and BR
|
# -> M and Flute and BR
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.can_flute(player) and basic_routes(state))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.has('Activated Flute', player) and basic_routes(state))
|
||||||
elif bombshop_entrance.name in Isolated_LW_entrances:
|
elif bombshop_entrance.name in Isolated_LW_entrances:
|
||||||
# 1. flute then basic routes
|
# 1. flute then basic routes
|
||||||
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
|
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
|
||||||
# -> Flute and BR
|
# -> Flute and BR
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and basic_routes(state))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and basic_routes(state))
|
||||||
elif bombshop_entrance.name in West_LW_DM_entrances:
|
elif bombshop_entrance.name in West_LW_DM_entrances:
|
||||||
# 1. flute then basic routes or mirror
|
# 1. flute then basic routes or mirror
|
||||||
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly.
|
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly.
|
||||||
# -> Flute and (M or BR)
|
# -> Flute and (M or BR)
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and (state.has_Mirror(player) or basic_routes(state)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and (state.has_Mirror(player) or basic_routes(state)))
|
||||||
elif bombshop_entrance.name in East_LW_DM_entrances:
|
elif bombshop_entrance.name in East_LW_DM_entrances:
|
||||||
# 1. flute then basic routes or mirror and hookshot
|
# 1. flute then basic routes or mirror and hookshot
|
||||||
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot
|
# Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot
|
||||||
# -> Flute and ((M and Hookshot) or BR)
|
# -> Flute and ((M and Hookshot) or BR)
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and ((state.has_Mirror(player) and state.has('Hookshot', player)) or basic_routes(state)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and ((state.has_Mirror(player) and state.has('Hookshot', player)) or basic_routes(state)))
|
||||||
elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)':
|
elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)':
|
||||||
# Same as East_LW_DM_entrances except navigation without BR requires Mitts
|
# Same as East_LW_DM_entrances except navigation without BR requires Mitts
|
||||||
# -> Flute and ((M and Hookshot and Mitts) or BR)
|
# -> Flute and ((M and Hookshot and Mitts) or BR)
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and ((state.has_Mirror(player) and state.has('Hookshot', player) and state.can_lift_heavy_rocks(player)) or basic_routes(state)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and ((state.has_Mirror(player) and state.has('Hookshot', player) and state.can_lift_heavy_rocks(player)) or basic_routes(state)))
|
||||||
elif bombshop_entrance.name in Castle_ledge_entrances:
|
elif bombshop_entrance.name in Castle_ledge_entrances:
|
||||||
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
|
# 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror
|
||||||
# 2. flute then basic routes
|
# 2. flute then basic routes
|
||||||
# -> M or (Flute and BR)
|
# -> M or (Flute and BR)
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) or (state.can_flute(player) and basic_routes(state)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) or (state.has('Activated Flute', player) and basic_routes(state)))
|
||||||
elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances:
|
elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances:
|
||||||
# Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and:
|
# Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and:
|
||||||
# 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes
|
# 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes
|
||||||
# 2. flute then basic routes
|
# 2. flute then basic routes
|
||||||
# -> (Mire access and M) or Flute) and BR
|
# -> (Mire access and M) or Flute) and BR
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has_Mirror(player)) or state.can_flute(player)) and basic_routes(state))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has_Mirror(player)) or state.has('Activated Flute', player)) and basic_routes(state))
|
||||||
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
||||||
# 1. Lift rock then basic_routes
|
# 1. Lift rock then basic_routes
|
||||||
# 2. flute then basic_routes
|
# 2. flute then basic_routes
|
||||||
# -> (Flute or G) and BR
|
# -> (Flute or G) and BR
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.can_lift_rocks(player)) and basic_routes(state))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or state.can_lift_rocks(player)) and basic_routes(state))
|
||||||
elif bombshop_entrance.name == 'Graveyard Cave':
|
elif bombshop_entrance.name == 'Graveyard Cave':
|
||||||
# 1. flute then basic routes
|
# 1. flute then basic routes
|
||||||
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge
|
# 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge
|
||||||
# -> (Flute or (M and P and West Dark World access) and BR
|
# -> (Flute or (M and P and West Dark World access) and BR
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))
|
||||||
elif bombshop_entrance.name in Mirror_from_SDW_entrances:
|
elif bombshop_entrance.name in Mirror_from_SDW_entrances:
|
||||||
# 1. flute then basic routes
|
# 1. flute then basic routes
|
||||||
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge
|
# 2. (has South dark world access) use existing mirror spot, mirror again off ledge
|
||||||
# -> (Flute or (M and South Dark World access) and BR
|
# -> (Flute or (M and South Dark World access) and BR
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('South Dark World', 'Region', player) and state.has_Mirror(player))) and basic_routes(state))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or (state.can_reach('South Dark World', 'Region', player) and state.has_Mirror(player))) and basic_routes(state))
|
||||||
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
||||||
# 1. walk down by lifting rock: needs gloves and pearl`
|
# 1. walk down by lifting rock: needs gloves and pearl`
|
||||||
# 2. walk down by hammering peg: needs hammer and pearl
|
# 2. walk down by hammering peg: needs hammer and pearl
|
||||||
|
@ -1182,11 +1184,11 @@ def set_big_bomb_rules(world, player):
|
||||||
# (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
|
# (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
|
||||||
# to account for insanity, must consider a way to escape without a cave for basic_routes
|
# to account for insanity, must consider a way to escape without a cave for basic_routes
|
||||||
# -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR)
|
# -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR)
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.can_flute(player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.has('Activated Flute', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)))
|
||||||
elif bombshop_entrance.name == 'Waterfall of Wishing':
|
elif bombshop_entrance.name == 'Waterfall of Wishing':
|
||||||
# same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which
|
# same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which
|
||||||
# means you need an escape route of either Flippers or Flute
|
# means you need an escape route of either Flippers or Flute
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)) and (basic_routes(state) or state.has_Mirror(player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Activated Flute', player)) and (basic_routes(state) or state.has_Mirror(player)))
|
||||||
|
|
||||||
|
|
||||||
def set_inverted_big_bomb_rules(world, player):
|
def set_inverted_big_bomb_rules(world, player):
|
||||||
|
@ -1325,50 +1327,50 @@ def set_inverted_big_bomb_rules(world, player):
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player))
|
||||||
elif bombshop_entrance.name in Isolated_LW_entrances:
|
elif bombshop_entrance.name in Isolated_LW_entrances:
|
||||||
# For these entrances, you cannot walk to the castle/pyramid and thus must use Mirror and then Flute.
|
# For these entrances, you cannot walk to the castle/pyramid and thus must use Mirror and then Flute.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) and state.has_Mirror(player))
|
||||||
elif bombshop_entrance.name in Northern_DW_entrances:
|
elif bombshop_entrance.name in Northern_DW_entrances:
|
||||||
# You can just fly with the Flute, you can take a long walk with Mitts and Hammer,
|
# You can just fly with the Flute, you can take a long walk with Mitts and Hammer,
|
||||||
# or you can leave a Mirror portal nearby and then walk to the castle to Mirror again.
|
# or you can leave a Mirror portal nearby and then walk to the castle to Mirror again.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
||||||
elif bombshop_entrance.name in Southern_DW_entrances:
|
elif bombshop_entrance.name in Southern_DW_entrances:
|
||||||
# This is the same as north DW without the Mitts rock present.
|
# This is the same as north DW without the Mitts rock present.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Hammer', player) or state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Hammer', player) or state.has('Activated Flute', player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
||||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||||
# There's just no way to escape these places with the bomb and no Flute.
|
# There's just no way to escape these places with the bomb and no Flute.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player))
|
||||||
elif bombshop_entrance.name in LW_walkable_entrances:
|
elif bombshop_entrance.name in LW_walkable_entrances:
|
||||||
# You can fly with the flute, or leave a mirror portal and walk through the light world
|
# You can fly with the flute, or leave a mirror portal and walk through the light world
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
||||||
elif bombshop_entrance.name in LW_bush_entrances:
|
elif bombshop_entrance.name in LW_bush_entrances:
|
||||||
# These entrances are behind bushes in LW so you need either Pearl or the tools to solve NDW bomb shop locations.
|
# These entrances are behind bushes in LW so you need either Pearl or the tools to solve NDW bomb shop locations.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and (state.can_flute(player) or state.has_Pearl(player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player))))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and (state.has('Activated Flute', player) or state.has_Pearl(player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player))))
|
||||||
elif bombshop_entrance.name == 'Dark World Shop':
|
elif bombshop_entrance.name == 'Dark World Shop':
|
||||||
# This is mostly the same as NDW but the Mirror path requires the Pearl, or using the Hammer
|
# This is mostly the same as NDW but the Mirror path requires the Pearl, or using the Hammer
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player) and (state.has_Pearl(player) or state.has('Hammer', player))))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player) and (state.has_Pearl(player) or state.has('Hammer', player))))
|
||||||
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
|
elif bombshop_entrance.name == 'Bumper Cave (Bottom)':
|
||||||
# This is mostly the same as NDW but the Mirror path requires being able to lift a rock.
|
# This is mostly the same as NDW but the Mirror path requires being able to lift a rock.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_lift_rocks(player) and state.can_reach('Light World', 'Region', player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or (state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.has_Mirror(player) and state.can_lift_rocks(player) and state.can_reach('Light World', 'Region', player)))
|
||||||
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
elif bombshop_entrance.name == 'Old Man Cave (West)':
|
||||||
# The three paths back are Mirror and DW walk, Mirror and Flute, or LW walk and then Mirror.
|
# The three paths back are Mirror and DW walk, Mirror and Flute, or LW walk and then Mirror.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and ((state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.can_lift_rocks(player) and state.has_Pearl(player)) or state.can_flute(player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and ((state.can_lift_heavy_rocks(player) and state.has('Hammer', player)) or (state.can_lift_rocks(player) and state.has_Pearl(player)) or state.has('Activated Flute', player)))
|
||||||
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
||||||
# You either need to Flute to 5 or cross the rock/hammer choice pass to the south.
|
# You either need to Flute to 5 or cross the rock/hammer choice pass to the south.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) or state.has('Hammer', player) or state.can_lift_rocks(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Activated Flute', player) or state.has('Hammer', player) or state.can_lift_rocks(player))
|
||||||
elif bombshop_entrance.name == 'Kings Grave':
|
elif bombshop_entrance.name == 'Kings Grave':
|
||||||
# Either lift the rock and walk to the castle to Mirror or Mirror immediately and Flute.
|
# Either lift the rock and walk to the castle to Mirror or Mirror immediately and Flute.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.can_lift_heavy_rocks(player)) and state.has_Mirror(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or state.can_lift_heavy_rocks(player)) and state.has_Mirror(player))
|
||||||
elif bombshop_entrance.name == 'Waterfall of Wishing':
|
elif bombshop_entrance.name == 'Waterfall of Wishing':
|
||||||
# You absolutely must be able to swim to return it from here.
|
# You absolutely must be able to swim to return it from here.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player) and state.has_Mirror(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player) and state.has_Mirror(player))
|
||||||
elif bombshop_entrance.name == 'Ice Palace':
|
elif bombshop_entrance.name == 'Ice Palace':
|
||||||
# You can swim to the dock or use the Flute to get off the island.
|
# You can swim to the dock or use the Flute to get off the island.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) or state.can_flute(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Flippers', player) or state.has('Activated Flute', player))
|
||||||
elif bombshop_entrance.name == 'Capacity Upgrade':
|
elif bombshop_entrance.name == 'Capacity Upgrade':
|
||||||
# You must Mirror but then can use either Ice Palace return path.
|
# You must Mirror but then can use either Ice Palace return path.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)) and state.has_Mirror(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Activated Flute', player)) and state.has_Mirror(player))
|
||||||
elif bombshop_entrance.name == 'Two Brothers House (West)':
|
elif bombshop_entrance.name == 'Two Brothers House (West)':
|
||||||
# First you must Mirror. Then you can either Flute, cross the peg bridge, or use the Agah 1 portal to Mirror again.
|
# First you must Mirror. Then you can either Flute, cross the peg bridge, or use the Agah 1 portal to Mirror again.
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has_Mirror(player))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Activated Flute', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) and state.has_Mirror(player))
|
||||||
elif bombshop_entrance.name in LW_inaccessible_entrances:
|
elif bombshop_entrance.name in LW_inaccessible_entrances:
|
||||||
# You can't get to the pyramid from these entrances without bomb duping.
|
# You can't get to the pyramid from these entrances without bomb duping.
|
||||||
raise Exception('No valid path to open Pyramid Fairy. (Could not route from %s)' % bombshop_entrance.name)
|
raise Exception('No valid path to open Pyramid Fairy. (Could not route from %s)' % bombshop_entrance.name)
|
||||||
|
|
200
Shops.py
200
Shops.py
|
@ -5,7 +5,7 @@ import logging
|
||||||
|
|
||||||
from BaseClasses import Location
|
from BaseClasses import Location
|
||||||
from EntranceShuffle import door_addresses
|
from EntranceShuffle import door_addresses
|
||||||
from Items import item_name_groups, item_table, ItemFactory
|
from Items import item_name_groups, item_table, ItemFactory, trap_replaceable, GetBeemizerItem
|
||||||
from Utils import int16_as_bytes
|
from Utils import int16_as_bytes
|
||||||
|
|
||||||
logger = logging.getLogger("Shops")
|
logger = logging.getLogger("Shops")
|
||||||
|
@ -96,6 +96,9 @@ class Shop():
|
||||||
if not self.inventory[slot]:
|
if not self.inventory[slot]:
|
||||||
raise ValueError("Inventory can't be pushed back if it doesn't exist")
|
raise ValueError("Inventory can't be pushed back if it doesn't exist")
|
||||||
|
|
||||||
|
if not self.can_push_inventory(slot):
|
||||||
|
logging.warning(f'Warning, there is already an item pushed into this slot.')
|
||||||
|
|
||||||
self.inventory[slot] = {
|
self.inventory[slot] = {
|
||||||
'item': item,
|
'item': item,
|
||||||
'price': price,
|
'price': price,
|
||||||
|
@ -145,45 +148,66 @@ def ShopSlotFill(world):
|
||||||
slot_num = int(location.name[-1]) - 1
|
slot_num = int(location.name[-1]) - 1
|
||||||
shop: Shop = location.parent_region.shop
|
shop: Shop = location.parent_region.shop
|
||||||
if not shop.can_push_inventory(slot_num) or location.shop_slot_disabled:
|
if not shop.can_push_inventory(slot_num) or location.shop_slot_disabled:
|
||||||
|
location.shop_slot_disabled = True
|
||||||
removed.add(location)
|
removed.add(location)
|
||||||
|
|
||||||
if removed:
|
if removed:
|
||||||
shop_slots -= removed
|
shop_slots -= removed
|
||||||
|
|
||||||
if shop_slots:
|
if shop_slots:
|
||||||
|
del shop_slots
|
||||||
|
|
||||||
from Fill import swap_location_item
|
from Fill import swap_location_item
|
||||||
# TODO: allow each game to register a blacklist to be used here?
|
# TODO: allow each game to register a blacklist to be used here?
|
||||||
blacklist_words = {"Rupee"}
|
blacklist_words = {"Rupee"}
|
||||||
blacklist_words = {item_name for item_name in item_table if any(
|
blacklist_words = {item_name for item_name in item_table if any(
|
||||||
blacklist_word in item_name for blacklist_word in blacklist_words)}
|
blacklist_word in item_name for blacklist_word in blacklist_words)}
|
||||||
blacklist_words.add("Bee")
|
blacklist_words.add("Bee")
|
||||||
candidates_per_sphere = list(list(sphere) for sphere in world.get_spheres())
|
|
||||||
|
|
||||||
candidate_condition = lambda location: not location.locked and \
|
locations_per_sphere = list(list(sphere) for sphere in world.get_spheres())
|
||||||
not location.shop_slot and \
|
|
||||||
not location.item.name in blacklist_words
|
|
||||||
|
|
||||||
# currently special care needs to be taken so that Shop.region.locations.item is identical to Shop.inventory
|
# currently special care needs to be taken so that Shop.region.locations.item is identical to Shop.inventory
|
||||||
# Potentially create Locations as needed and make inventory the only source, to prevent divergence
|
# Potentially create Locations as needed and make inventory the only source, to prevent divergence
|
||||||
cumu_weights = []
|
cumu_weights = []
|
||||||
|
shops_per_sphere = []
|
||||||
|
candidates_per_sphere = []
|
||||||
|
|
||||||
for sphere in candidates_per_sphere:
|
# sort spheres into piles of valid candidates and shops
|
||||||
|
for sphere in locations_per_sphere:
|
||||||
|
current_shops_slots = []
|
||||||
|
current_candidates = []
|
||||||
|
shops_per_sphere.append(current_shops_slots)
|
||||||
|
candidates_per_sphere.append(current_candidates)
|
||||||
|
for location in sphere:
|
||||||
|
if location.shop_slot:
|
||||||
|
if not location.shop_slot_disabled:
|
||||||
|
current_shops_slots.append(location)
|
||||||
|
elif not location.locked and not location.item.name in blacklist_words:
|
||||||
|
current_candidates.append(location)
|
||||||
if cumu_weights:
|
if cumu_weights:
|
||||||
x = cumu_weights[-1]
|
x = cumu_weights[-1]
|
||||||
else:
|
else:
|
||||||
x = 0
|
x = 0
|
||||||
cumu_weights.append(len(sphere) + x)
|
cumu_weights.append(len(current_candidates) + x)
|
||||||
world.random.shuffle(sphere)
|
|
||||||
|
|
||||||
for i, sphere in enumerate(candidates_per_sphere):
|
world.random.shuffle(current_candidates)
|
||||||
current_shop_slots = [location for location in sphere if location.shop_slot and not location.shop_slot_disabled]
|
|
||||||
|
del locations_per_sphere
|
||||||
|
|
||||||
|
total_spheres = len(candidates_per_sphere)
|
||||||
|
|
||||||
|
for i, current_shop_slots in enumerate(shops_per_sphere):
|
||||||
if current_shop_slots:
|
if current_shop_slots:
|
||||||
|
candidate_sphere_ids = list(range(i, total_spheres))
|
||||||
for location in current_shop_slots:
|
for location in current_shop_slots:
|
||||||
shop: Shop = location.parent_region.shop
|
shop: Shop = location.parent_region.shop
|
||||||
swapping_sphere = world.random.choices(candidates_per_sphere[i:], cum_weights=cumu_weights[i:])[0]
|
swapping_sphere_id = world.random.choices(candidate_sphere_ids,
|
||||||
|
cum_weights=cumu_weights[i:])[0]
|
||||||
|
swapping_sphere: list = candidates_per_sphere[swapping_sphere_id]
|
||||||
for c in swapping_sphere: # chosen item locations
|
for c in swapping_sphere: # chosen item locations
|
||||||
if candidate_condition(c) and c.item_rule(location.item) and location.item_rule(c.item):
|
if c.item_rule(location.item) and location.item_rule(c.item):
|
||||||
swap_location_item(c, location, check_locked=False)
|
swap_location_item(c, location, check_locked=False)
|
||||||
logger.debug(f'Swapping {c} into {location}:: {location.item}')
|
logger.debug(f'Swapping {c} into {location}:: {location.item}')
|
||||||
break
|
break
|
||||||
|
@ -193,18 +217,22 @@ def ShopSlotFill(world):
|
||||||
logger.warning("Ran out of ShopShuffle Item candidate locations.")
|
logger.warning("Ran out of ShopShuffle Item candidate locations.")
|
||||||
location.shop_slot_disabled = True
|
location.shop_slot_disabled = True
|
||||||
continue
|
continue
|
||||||
item_name = location.item.name
|
|
||||||
if any(x in item_name for x in ['Single Bomb', 'Single Arrow']):
|
|
||||||
price = world.random.randrange(1, 7)
|
|
||||||
elif any(x in item_name for x in ['Arrows', 'Bombs', 'Clock']):
|
|
||||||
price = world.random.randrange(4, 24)
|
|
||||||
elif any(x in item_name for x in ['Compass', 'Map', 'Small Key', 'Piece of Heart']):
|
|
||||||
price = world.random.randrange(10, 30)
|
|
||||||
else:
|
|
||||||
price = world.random.randrange(10, 60)
|
|
||||||
|
|
||||||
price *= 5
|
# remove candidate
|
||||||
shop.push_inventory(int(location.name[-1]) - 1, item_name, price, 1,
|
swapping_sphere.remove(c)
|
||||||
|
cumu_weights[swapping_sphere_id] -= 1
|
||||||
|
|
||||||
|
item_name = location.item.name
|
||||||
|
if any(x in item_name for x in ['Compass', 'Map', 'Single Bomb', 'Single Arrow', 'Piece of Heart']):
|
||||||
|
price = world.random.randrange(1, 7)
|
||||||
|
elif any(x in item_name for x in ['Arrow', 'Bomb', 'Clock']):
|
||||||
|
price = world.random.randrange(2, 14)
|
||||||
|
elif any(x in item_name for x in ['Small Key', 'Heart']):
|
||||||
|
price = world.random.randrange(4, 28)
|
||||||
|
else:
|
||||||
|
price = world.random.randrange(8, 56)
|
||||||
|
|
||||||
|
shop.push_inventory(int(location.name[-1]) - 1, item_name, price * 5, 1,
|
||||||
location.item.player if location.item.player != location.player else 0)
|
location.item.player if location.item.player != location.player else 0)
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,11 +266,16 @@ def create_shops(world, player: int):
|
||||||
keeper = world.random.choice([0xA0, 0xC1, 0xFF])
|
keeper = world.random.choice([0xA0, 0xC1, 0xFF])
|
||||||
player_shop_table[name] = ShopData(typ, shop_id, keeper, custom, locked, new_items, sram_offset)
|
player_shop_table[name] = ShopData(typ, shop_id, keeper, custom, locked, new_items, sram_offset)
|
||||||
if world.mode[player] == "inverted":
|
if world.mode[player] == "inverted":
|
||||||
|
# make sure that blue potion is available in inverted, special case locked = None; lock when done.
|
||||||
player_shop_table["Dark Lake Hylia Shop"] = \
|
player_shop_table["Dark Lake Hylia Shop"] = \
|
||||||
player_shop_table["Dark Lake Hylia Shop"]._replace(locked=True, items=_inverted_hylia_shop_defaults)
|
player_shop_table["Dark Lake Hylia Shop"]._replace(items=_inverted_hylia_shop_defaults, locked=None)
|
||||||
|
chance_100 = int(world.retro[player])*0.25+int(world.keyshuffle[player] == "universal") * 0.5
|
||||||
for region_name, (room_id, type, shopkeeper, custom, locked, inventory, sram_offset) in player_shop_table.items():
|
for region_name, (room_id, type, shopkeeper, custom, locked, inventory, sram_offset) in player_shop_table.items():
|
||||||
region = world.get_region(region_name, player)
|
region = world.get_region(region_name, player)
|
||||||
shop: Shop = shop_class_mapping[type](region, room_id, shopkeeper, custom, locked, sram_offset)
|
shop: Shop = shop_class_mapping[type](region, room_id, shopkeeper, custom, locked, sram_offset)
|
||||||
|
# special case: allow shop slots, but do not allow overwriting of base inventory behind them
|
||||||
|
if locked is None:
|
||||||
|
shop.locked = True
|
||||||
region.shop = shop
|
region.shop = shop
|
||||||
world.shops.append(shop)
|
world.shops.append(shop)
|
||||||
for index, item in enumerate(inventory):
|
for index, item in enumerate(inventory):
|
||||||
|
@ -255,12 +288,15 @@ def create_shops(world, player: int):
|
||||||
loc.locked = True
|
loc.locked = True
|
||||||
if single_purchase_slots.pop():
|
if single_purchase_slots.pop():
|
||||||
if world.goal[player] != 'icerodhunt':
|
if world.goal[player] != 'icerodhunt':
|
||||||
additional_item = 'Rupees (50)' # world.random.choice(['Rupees (50)', 'Rupees (100)', 'Rupees (300)'])
|
if world.random.random() < chance_100:
|
||||||
|
additional_item = 'Rupees (100)'
|
||||||
else:
|
else:
|
||||||
additional_item = 'Nothing'
|
additional_item = 'Rupees (50)'
|
||||||
|
else:
|
||||||
|
additional_item = GetBeemizerItem(world, player, 'Nothing')
|
||||||
loc.item = ItemFactory(additional_item, player)
|
loc.item = ItemFactory(additional_item, player)
|
||||||
else:
|
else:
|
||||||
loc.item = ItemFactory('Nothing', player)
|
loc.item = ItemFactory(GetBeemizerItem(world, player, 'Nothing'), player)
|
||||||
loc.shop_slot_disabled = True
|
loc.shop_slot_disabled = True
|
||||||
shop.region.locations.append(loc)
|
shop.region.locations.append(loc)
|
||||||
world.dynamic_locations.append(loc)
|
world.dynamic_locations.append(loc)
|
||||||
|
@ -272,7 +308,7 @@ class ShopData(NamedTuple):
|
||||||
type: ShopType
|
type: ShopType
|
||||||
shopkeeper: int
|
shopkeeper: int
|
||||||
custom: bool
|
custom: bool
|
||||||
locked: bool
|
locked: Optional[bool]
|
||||||
items: List
|
items: List
|
||||||
sram_offset: int
|
sram_offset: int
|
||||||
|
|
||||||
|
@ -322,3 +358,109 @@ shop_generation_types = {
|
||||||
'bottle': [('Small Heart', 10), ('Apple', 50), ('Bee', 10), ('Good Bee', 100), ('Faerie', 100), ('Magic Jar', 100)],
|
'bottle': [('Small Heart', 10), ('Apple', 50), ('Bee', 10), ('Good Bee', 100), ('Faerie', 100), ('Magic Jar', 100)],
|
||||||
'time': [('Red Clock', 100), ('Blue Clock', 200), ('Green Clock', 300)],
|
'time': [('Red Clock', 100), ('Blue Clock', 200), ('Green Clock', 300)],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_up_shops(world, player: int):
|
||||||
|
# TODO: move hard+ mode changes for shields here, utilizing the new shops
|
||||||
|
|
||||||
|
if world.retro[player]:
|
||||||
|
rss = world.get_region('Red Shield Shop', player).shop
|
||||||
|
replacement_items = [['Red Potion', 150], ['Green Potion', 75], ['Blue Potion', 200], ['Bombs (10)', 50],
|
||||||
|
['Blue Shield', 50], ['Small Heart', 10]] # Can't just replace the single arrow with 10 arrows as retro doesn't need them.
|
||||||
|
if world.keyshuffle[player] == "universal":
|
||||||
|
replacement_items.append(['Small Key (Universal)', 100])
|
||||||
|
replacement_item = world.random.choice(replacement_items)
|
||||||
|
rss.add_inventory(2, 'Single Arrow', 80, 1, replacement_item[0], replacement_item[1])
|
||||||
|
rss.locked = True
|
||||||
|
|
||||||
|
if world.keyshuffle[player] == "universal" or world.retro[player]:
|
||||||
|
for shop in world.random.sample([s for s in world.shops if
|
||||||
|
s.custom and not s.locked and s.type == ShopType.Shop and s.region.player == player],
|
||||||
|
5):
|
||||||
|
shop.locked = True
|
||||||
|
slots = [0, 1, 2]
|
||||||
|
world.random.shuffle(slots)
|
||||||
|
slots = iter(slots)
|
||||||
|
if world.keyshuffle[player] == "universal":
|
||||||
|
shop.add_inventory(next(slots), 'Small Key (Universal)', 100)
|
||||||
|
if world.retro[player]:
|
||||||
|
shop.push_inventory(next(slots), 'Single Arrow', 80)
|
||||||
|
|
||||||
|
|
||||||
|
def shuffle_shops(world, items, player: int):
|
||||||
|
option = world.shop_shuffle[player]
|
||||||
|
if 'u' in option:
|
||||||
|
progressive = world.progressive[player]
|
||||||
|
progressive = world.random.choice([True, False]) if progressive == 'random' else progressive == 'on'
|
||||||
|
progressive &= world.goal == 'icerodhunt'
|
||||||
|
new_items = ["Bomb Upgrade (+5)"] * 6
|
||||||
|
new_items.append("Bomb Upgrade (+5)" if progressive else "Bomb Upgrade (+10)")
|
||||||
|
|
||||||
|
if not world.retro[player]:
|
||||||
|
new_items += ["Arrow Upgrade (+5)"] * 6
|
||||||
|
new_items.append("Arrow Upgrade (+5)" if progressive else "Arrow Upgrade (+10)")
|
||||||
|
|
||||||
|
world.random.shuffle(new_items) # Decide what gets tossed randomly if it can't insert everything.
|
||||||
|
|
||||||
|
capacityshop: Optional[Shop] = None
|
||||||
|
for shop in world.shops:
|
||||||
|
if shop.type == ShopType.UpgradeShop and shop.region.player == player and \
|
||||||
|
shop.region.name == "Capacity Upgrade":
|
||||||
|
shop.clear_inventory()
|
||||||
|
capacityshop = shop
|
||||||
|
|
||||||
|
if world.goal[player] != 'icerodhunt':
|
||||||
|
for i, item in enumerate(items):
|
||||||
|
if item.name in trap_replaceable:
|
||||||
|
items[i] = ItemFactory(new_items.pop(), player)
|
||||||
|
if not new_items:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
logging.warning(f"Not all upgrades put into Player{player}' item pool. Putting remaining items in Capacity Upgrade shop instead.")
|
||||||
|
bombupgrades = sum(1 for item in new_items if 'Bomb Upgrade' in item)
|
||||||
|
arrowupgrades = sum(1 for item in new_items if 'Arrow Upgrade' in item)
|
||||||
|
if bombupgrades:
|
||||||
|
capacityshop.add_inventory(1, 'Bomb Upgrade (+5)', 100, bombupgrades)
|
||||||
|
if arrowupgrades:
|
||||||
|
capacityshop.add_inventory(1, 'Arrow Upgrade (+5)', 100, arrowupgrades)
|
||||||
|
else:
|
||||||
|
for item in new_items:
|
||||||
|
world.push_precollected(ItemFactory(item, player))
|
||||||
|
|
||||||
|
if 'p' in option or 'i' in option:
|
||||||
|
shops = []
|
||||||
|
upgrade_shops = []
|
||||||
|
total_inventory = []
|
||||||
|
for shop in world.shops:
|
||||||
|
if shop.region.player == player:
|
||||||
|
if shop.type == ShopType.UpgradeShop:
|
||||||
|
upgrade_shops.append(shop)
|
||||||
|
elif shop.type == ShopType.Shop and not shop.locked:
|
||||||
|
shops.append(shop)
|
||||||
|
total_inventory.extend(shop.inventory)
|
||||||
|
|
||||||
|
if 'p' in option:
|
||||||
|
def price_adjust(price: int) -> int:
|
||||||
|
# it is important that a base price of 0 always returns 0 as new price!
|
||||||
|
adjust = 2 if price < 100 else 5
|
||||||
|
return int((price / adjust) * (0.5 + world.random.random() * 1.5)) * adjust
|
||||||
|
|
||||||
|
def adjust_item(item):
|
||||||
|
if item:
|
||||||
|
item["price"] = price_adjust(item["price"])
|
||||||
|
item['replacement_price'] = price_adjust(item["price"])
|
||||||
|
|
||||||
|
for item in total_inventory:
|
||||||
|
adjust_item(item)
|
||||||
|
for shop in upgrade_shops:
|
||||||
|
for item in shop.inventory:
|
||||||
|
adjust_item(item)
|
||||||
|
|
||||||
|
if 'i' in option:
|
||||||
|
world.random.shuffle(total_inventory)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for shop in shops:
|
||||||
|
slots = shop.slots
|
||||||
|
shop.inventory = total_inventory[i:i + slots]
|
||||||
|
i += slots
|
||||||
|
|
6
Text.py
6
Text.py
|
@ -1443,7 +1443,7 @@ class TextTable(object):
|
||||||
'zora_meeting',
|
'zora_meeting',
|
||||||
'zora_tells_cost',
|
'zora_tells_cost',
|
||||||
'zora_get_flippers',
|
'zora_get_flippers',
|
||||||
#'zora_no_cash',
|
'zora_no_cash',
|
||||||
'zora_no_buy_item',
|
'zora_no_buy_item',
|
||||||
'agahnim_zelda_teleport',
|
'agahnim_zelda_teleport',
|
||||||
'agahnim_magic_running_away',
|
'agahnim_magic_running_away',
|
||||||
|
@ -1725,7 +1725,7 @@ class TextTable(object):
|
||||||
text['game_race_boy_already_won'] = CompressedTextMapper.convert("You already have your prize, dingus!")
|
text['game_race_boy_already_won'] = CompressedTextMapper.convert("You already have your prize, dingus!")
|
||||||
# D0
|
# D0
|
||||||
text['game_race_boy_sneaky'] = CompressedTextMapper.convert("Thought you could sneak in, eh?")
|
text['game_race_boy_sneaky'] = CompressedTextMapper.convert("Thought you could sneak in, eh?")
|
||||||
text['bottle_vendor_choice'] = CompressedTextMapper.convert("I gots bottles.\nYous gots 100 rupees?\n ≥ I want\n no way!")
|
text['bottle_vendor_choice'] = CompressedTextMapper.convert("I gots bottles.\nYous gots 100 rupees?\n ≥ I want\n no way!\n{CHOICE}")
|
||||||
text['bottle_vendor_get'] = CompressedTextMapper.convert("Nice! Hold it up son! Show the world what you got!")
|
text['bottle_vendor_get'] = CompressedTextMapper.convert("Nice! Hold it up son! Show the world what you got!")
|
||||||
text['bottle_vendor_no'] = CompressedTextMapper.convert("Fine! I didn't want your money anyway.")
|
text['bottle_vendor_no'] = CompressedTextMapper.convert("Fine! I didn't want your money anyway.")
|
||||||
text['bottle_vendor_already_collected'] = CompressedTextMapper.convert("Dude! You already have it.")
|
text['bottle_vendor_already_collected'] = CompressedTextMapper.convert("Dude! You already have it.")
|
||||||
|
@ -1884,7 +1884,7 @@ class TextTable(object):
|
||||||
text['item_get_whole_heart'] = CompressedTextMapper.convert("You got a whole ♥!!\nGo you!")
|
text['item_get_whole_heart'] = CompressedTextMapper.convert("You got a whole ♥!!\nGo you!")
|
||||||
text['item_get_sanc_heart'] = CompressedTextMapper.convert("You got a whole ♥!\nGo you!")
|
text['item_get_sanc_heart'] = CompressedTextMapper.convert("You got a whole ♥!\nGo you!")
|
||||||
text['fairy_fountain_refill'] = CompressedTextMapper.convert("Well done, lettuce have a cup of tea…")
|
text['fairy_fountain_refill'] = CompressedTextMapper.convert("Well done, lettuce have a cup of tea…")
|
||||||
text['death_mountain_bullied_no_pearl'] = CompressedTextMapper.convert("The following license applies to the base patch for the randomizer.\n\nCopyright (c) 2017 LLCoolDave\n\nCopyright (c) 2020 Berserker66\n\nCopyright (c) 2020 CaitSith2\n\nCopyright 2016, 2017 Equilateral IT\n\n Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.")
|
text['death_mountain_bullied_no_pearl'] = CompressedTextMapper.convert("The following license applies to the base patch for the randomizer.\n\nCopyright (c) 2017 LLCoolDave\n\nCopyright (c) 2021 Berserker66\n\nCopyright (c) 2021 CaitSith2\n\nCopyright 2016, 2017 Equilateral IT\n\n Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.")
|
||||||
text['death_mountain_bullied_with_pearl'] = CompressedTextMapper.convert("The software is provided \"as is\", without warranty of any kind, express or implied, including but not limited to the warranties of\nmerchantability,\nfitness for a particular purpose and\nnoninfringement.\nIn no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the software.")
|
text['death_mountain_bullied_with_pearl'] = CompressedTextMapper.convert("The software is provided \"as is\", without warranty of any kind, express or implied, including but not limited to the warranties of\nmerchantability,\nfitness for a particular purpose and\nnoninfringement.\nIn no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the software.")
|
||||||
text['death_mountain_bully_no_pearl'] = CompressedTextMapper.convert("Add garlic, ginger and apple and cook for 2 minutes. Add carrots, potatoes, garam masala and curry powder and stir well. Add tomato paste, stir well and slowly add red wine and bring to a boil. Add sugar, soy sauce and water, stir and bring to a boil again.")
|
text['death_mountain_bully_no_pearl'] = CompressedTextMapper.convert("Add garlic, ginger and apple and cook for 2 minutes. Add carrots, potatoes, garam masala and curry powder and stir well. Add tomato paste, stir well and slowly add red wine and bring to a boil. Add sugar, soy sauce and water, stir and bring to a boil again.")
|
||||||
text['death_mountain_bully_with_pearl'] = CompressedTextMapper.convert("I think I forgot how to smile…")
|
text['death_mountain_bully_with_pearl'] = CompressedTextMapper.convert("I think I forgot how to smile…")
|
||||||
|
|
6
Utils.py
6
Utils.py
|
@ -13,7 +13,7 @@ class Version(typing.NamedTuple):
|
||||||
micro: int
|
micro: int
|
||||||
|
|
||||||
|
|
||||||
__version__ = "4.0.0"
|
__version__ = "4.1.0"
|
||||||
_version_tuple = tuplize_version(__version__)
|
_version_tuple = tuplize_version(__version__)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -343,8 +343,8 @@ def get_adjuster_settings(romfile: str) -> typing.Tuple[str, bool]:
|
||||||
f"Enter yes, no or never: ")
|
f"Enter yes, no or never: ")
|
||||||
if adjust_wanted and adjust_wanted.startswith("y"):
|
if adjust_wanted and adjust_wanted.startswith("y"):
|
||||||
adjusted = True
|
adjusted = True
|
||||||
import AdjusterMain
|
import Adjuster
|
||||||
_, romfile = AdjusterMain.adjust(adjuster_settings)
|
_, romfile = Adjuster.adjust(adjuster_settings)
|
||||||
elif adjust_wanted and "never" in adjust_wanted:
|
elif adjust_wanted and "never" in adjust_wanted:
|
||||||
persistent_store("adjuster", "never_adjust", True)
|
persistent_store("adjuster", "never_adjust", True)
|
||||||
return romfile, False
|
return romfile, False
|
||||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
import logging
|
import logging
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
|
import concurrent.futures
|
||||||
import sys
|
import sys
|
||||||
import typing
|
import typing
|
||||||
import time
|
import time
|
||||||
|
@ -136,6 +137,7 @@ def autohost(config: dict):
|
||||||
|
|
||||||
multiworlds = {}
|
multiworlds = {}
|
||||||
|
|
||||||
|
guardians = concurrent.futures.ThreadPoolExecutor(2, thread_name_prefix="Guardian")
|
||||||
|
|
||||||
class MultiworldInstance():
|
class MultiworldInstance():
|
||||||
def __init__(self, room: Room, config: dict):
|
def __init__(self, room: Room, config: dict):
|
||||||
|
@ -153,12 +155,18 @@ class MultiworldInstance():
|
||||||
args=(self.room_id, self.ponyconfig),
|
args=(self.room_id, self.ponyconfig),
|
||||||
name="MultiHost")
|
name="MultiHost")
|
||||||
self.process.start()
|
self.process.start()
|
||||||
|
self.guardian = guardians.submit(self._collect)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.process:
|
if self.process:
|
||||||
self.process.terminate()
|
self.process.terminate()
|
||||||
self.process = None
|
self.process = None
|
||||||
|
|
||||||
|
def _collect(self):
|
||||||
|
self.process.join() # wait for process to finish
|
||||||
|
self.process = None
|
||||||
|
self.guardian = None
|
||||||
|
|
||||||
|
|
||||||
from .models import Room, Generation, STATE_QUEUED, STATE_STARTED, STATE_ERROR, db, Seed
|
from .models import Room, Generation, STATE_QUEUED, STATE_STARTED, STATE_ERROR, db, Seed
|
||||||
from .customserver import run_server_process
|
from .customserver import run_server_process
|
||||||
|
|
|
@ -55,7 +55,7 @@ window.addEventListener('load', () => {
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
adjustTableHeight();
|
adjustTableHeight();
|
||||||
tables.draw()
|
tables.draw();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".table-wrapper").scrollsync({
|
$(".table-wrapper").scrollsync({
|
||||||
|
|
|
@ -126,10 +126,8 @@ done so already, please do this now. SD2SNES and FXPak Pro users may download th
|
||||||
[on this page](http://usb2snes.com/#supported-platforms).
|
[on this page](http://usb2snes.com/#supported-platforms).
|
||||||
|
|
||||||
1. Close your emulator, which may have auto-launched.
|
1. Close your emulator, which may have auto-launched.
|
||||||
2. Close QUsb2Snes, which launched automatically with the client.
|
2. Power on your device and load the ROM.
|
||||||
3. Launch the appropriate version of QUsb2Snes (v0.7.16).
|
3. Observe the client window now shows "SNES Device: Connected", and lists the name of your device.
|
||||||
4. Power on your device and load the ROM.
|
|
||||||
5. Observe the client window now shows "SNES Device: Connected", and lists the name of your device.
|
|
||||||
|
|
||||||
### Connect to the MultiServer
|
### Connect to the MultiServer
|
||||||
The patch file which launched your client should have automatically connected you to the MultiServer.
|
The patch file which launched your client should have automatically connected you to the MultiServer.
|
||||||
|
|
|
@ -2,9 +2,17 @@ let spriteData = null;
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
const gameSettings = document.getElementById('weighted-settings');
|
const gameSettings = document.getElementById('weighted-settings');
|
||||||
Promise.all([fetchPlayerSettingsYaml(), fetchPlayerSettingsJson(), fetchSpriteData()]).then((results) => {
|
Promise.all([fetchWeightedSettingsYaml(), fetchWeightedSettingsJson(), fetchSpriteData()]).then((results) => {
|
||||||
// Load YAML into object
|
// Load YAML into object
|
||||||
const sourceData = jsyaml.safeLoad(results[0], { json: true });
|
const sourceData = jsyaml.safeLoad(results[0], { json: true });
|
||||||
|
const wsVersion = sourceData.ws_version;
|
||||||
|
delete sourceData.ws_version; // Do not include the settings version number in the export
|
||||||
|
|
||||||
|
// Check if settings exist in localStorage. If no settings are present, this is a first load (or reset to default)
|
||||||
|
// and the version number should be silently updated
|
||||||
|
if (!localStorage.getItem('weightedSettings1')) {
|
||||||
|
localStorage.setItem('wsVersion', wsVersion);
|
||||||
|
}
|
||||||
|
|
||||||
// Update localStorage with three settings objects. Preserve original objects if present.
|
// Update localStorage with three settings objects. Preserve original objects if present.
|
||||||
for (let i=1; i<=3; i++) {
|
for (let i=1; i<=3; i++) {
|
||||||
|
@ -25,6 +33,16 @@ window.addEventListener('load', () => {
|
||||||
document.getElementById('export-button').addEventListener('click', exportSettings);
|
document.getElementById('export-button').addEventListener('click', exportSettings);
|
||||||
document.getElementById('reset-to-default').addEventListener('click', resetToDefaults);
|
document.getElementById('reset-to-default').addEventListener('click', resetToDefaults);
|
||||||
adjustHeaderWidth();
|
adjustHeaderWidth();
|
||||||
|
|
||||||
|
if (localStorage.getItem('wsVersion') !== wsVersion) {
|
||||||
|
const userWarning = document.getElementById('user-warning');
|
||||||
|
const messageSpan = document.createElement('span');
|
||||||
|
messageSpan.innerHTML = "A new version of the weighted settings file is available. Click here to update!" +
|
||||||
|
"<br />Be aware this will also reset your presets, so you should export them now if you want to save them.";
|
||||||
|
userWarning.appendChild(messageSpan);
|
||||||
|
userWarning.style.display = 'block';
|
||||||
|
userWarning.addEventListener('click', resetToDefaults);
|
||||||
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
gameSettings.innerHTML = `
|
gameSettings.innerHTML = `
|
||||||
|
@ -37,7 +55,7 @@ window.addEventListener('load', () => {
|
||||||
document.getElementById('generate-race').addEventListener('click', () => generateGame(true));
|
document.getElementById('generate-race').addEventListener('click', () => generateGame(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchPlayerSettingsYaml = () => new Promise((resolve, reject) => {
|
const fetchWeightedSettingsYaml = () => new Promise((resolve, reject) => {
|
||||||
const ajax = new XMLHttpRequest();
|
const ajax = new XMLHttpRequest();
|
||||||
ajax.onreadystatechange = () => {
|
ajax.onreadystatechange = () => {
|
||||||
if (ajax.readyState !== 4) { return; }
|
if (ajax.readyState !== 4) { return; }
|
||||||
|
@ -51,7 +69,7 @@ const fetchPlayerSettingsYaml = () => new Promise((resolve, reject) => {
|
||||||
ajax.send();
|
ajax.send();
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchPlayerSettingsJson = () => new Promise((resolve, reject) => {
|
const fetchWeightedSettingsJson = () => new Promise((resolve, reject) => {
|
||||||
const ajax = new XMLHttpRequest();
|
const ajax = new XMLHttpRequest();
|
||||||
ajax.onreadystatechange = () => {
|
ajax.onreadystatechange = () => {
|
||||||
if (ajax.readyState !== 4) { return; }
|
if (ajax.readyState !== 4) { return; }
|
||||||
|
@ -113,6 +131,7 @@ const handleOptionChange = (event) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const populateSettings = () => {
|
const populateSettings = () => {
|
||||||
|
buildSpriteOptions();
|
||||||
const presetNumber = document.getElementById('preset-number').value;
|
const presetNumber = document.getElementById('preset-number').value;
|
||||||
const settings = JSON.parse(localStorage.getItem(`weightedSettings${presetNumber}`))
|
const settings = JSON.parse(localStorage.getItem(`weightedSettings${presetNumber}`))
|
||||||
const settingsInputs = Array.from(document.querySelectorAll('.setting'));
|
const settingsInputs = Array.from(document.querySelectorAll('.setting'));
|
||||||
|
@ -206,7 +225,21 @@ const buildUI = (settings, spriteData) => {
|
||||||
settingsWrapper.appendChild(spriteOptionsHeader);
|
settingsWrapper.appendChild(spriteOptionsHeader);
|
||||||
|
|
||||||
const spriteOptionsWrapper = document.createElement('div');
|
const spriteOptionsWrapper = document.createElement('div');
|
||||||
|
spriteOptionsWrapper.setAttribute('id', 'sprite-options-wrapper');
|
||||||
spriteOptionsWrapper.className = 'setting-wrapper';
|
spriteOptionsWrapper.className = 'setting-wrapper';
|
||||||
|
settingsWrapper.appendChild(spriteOptionsWrapper);
|
||||||
|
|
||||||
|
// Append sprite picker
|
||||||
|
settingsWrapper.appendChild(buildSpritePicker(spriteData));
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildSpriteOptions = () => {
|
||||||
|
const spriteOptionsWrapper = document.getElementById('sprite-options-wrapper');
|
||||||
|
|
||||||
|
// Clear the contents of the wrapper div
|
||||||
|
while(spriteOptionsWrapper.firstChild){
|
||||||
|
spriteOptionsWrapper.removeChild(spriteOptionsWrapper.lastChild);
|
||||||
|
}
|
||||||
|
|
||||||
const spriteOptionsTitle = document.createElement('span');
|
const spriteOptionsTitle = document.createElement('span');
|
||||||
spriteOptionsTitle.className = 'title-span';
|
spriteOptionsTitle.className = 'title-span';
|
||||||
|
@ -240,11 +273,6 @@ const buildUI = (settings, spriteData) => {
|
||||||
|
|
||||||
spriteOptionsTable.appendChild(tbody);
|
spriteOptionsTable.appendChild(tbody);
|
||||||
spriteOptionsWrapper.appendChild(spriteOptionsTable);
|
spriteOptionsWrapper.appendChild(spriteOptionsTable);
|
||||||
|
|
||||||
settingsWrapper.appendChild(spriteOptionsWrapper);
|
|
||||||
|
|
||||||
// Append sprite picker
|
|
||||||
settingsWrapper.appendChild(buildSpritePicker(spriteData));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildRangeSettings = (parentElement, settings) => {
|
const buildRangeSettings = (parentElement, settings) => {
|
||||||
|
|
|
@ -406,6 +406,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pyramid_open": {
|
||||||
|
"keyString": "pyramid_open",
|
||||||
|
"friendlyName": "Pyramid Open",
|
||||||
|
"description": "",
|
||||||
|
"inputType": "range",
|
||||||
|
"subOptions": {
|
||||||
|
"goal": {
|
||||||
|
"keyString": "pyramid_open.goal",
|
||||||
|
"friendlyName": "Goal",
|
||||||
|
"description": "Opens the pyramid if the goal requires you to kill Ganon, unless the goal is Slow Ganon or All Dungeons.",
|
||||||
|
"defaultValue": 50
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"keyString": "pyramid_open.auto",
|
||||||
|
"friendlyName": "Auto",
|
||||||
|
"description": "Same as Goal, but also opens when any non-dungeon entrance shuffle is used.",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
"yes": {
|
||||||
|
"keyString": "pyramid_open.yes",
|
||||||
|
"friendlyName": "Always Open",
|
||||||
|
"description": "Pyramid hole is always open. Ganon's vulnerable condition is still required before he can he hurt.",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
"no": {
|
||||||
|
"keyString": "pyramid_open.no",
|
||||||
|
"friendlyName": "Always Closed",
|
||||||
|
"description": "Pyramid hole is always closed until you defeat Agahnim atop Ganon's Tower.",
|
||||||
|
"defaultValue": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"triforce_pieces_required": {
|
"triforce_pieces_required": {
|
||||||
"keyString": "triforce_pieces_required",
|
"keyString": "triforce_pieces_required",
|
||||||
"friendlyName": "Triforce Pieces Required",
|
"friendlyName": "Triforce Pieces Required",
|
||||||
|
@ -1135,7 +1167,7 @@
|
||||||
"beemizer": {
|
"beemizer": {
|
||||||
"keyString": "beemizer",
|
"keyString": "beemizer",
|
||||||
"friendlyName": "Beemizer",
|
"friendlyName": "Beemizer",
|
||||||
"description": "Remove items from the global item pool and replace them with single bees and bee traps.",
|
"description": "Remove non-health items from the global item pool and replace them with single bees and bee traps.",
|
||||||
"inputType": "range",
|
"inputType": "range",
|
||||||
"subOptions": {
|
"subOptions": {
|
||||||
"0": {
|
"0": {
|
||||||
|
@ -1147,25 +1179,25 @@
|
||||||
"1": {
|
"1": {
|
||||||
"keyString": "beemizer.1",
|
"keyString": "beemizer.1",
|
||||||
"friendlyName": "Level 1",
|
"friendlyName": "Level 1",
|
||||||
"description": "25% of the non-essential item pool is replaced with bee traps.",
|
"description": "25% of rupees, bombs and arrows are replaced with bees, of which 60% are traps and 40% single bees",
|
||||||
"defaultValue": 1
|
"defaultValue": 1
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"keyString": "beemizer.2",
|
"keyString": "beemizer.2",
|
||||||
"friendlyName": "Level 2",
|
"friendlyName": "Level 2",
|
||||||
"description": "60% of the non-essential item pool is replaced with bee traps, of which 20% could be single bees.",
|
"description": "50% of rupees, bombs and arrows are replaced with bees, of which 70% are traps and 30% single bees",
|
||||||
"defaultValue": 2
|
"defaultValue": 2
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"keyString": "beemizer.3",
|
"keyString": "beemizer.3",
|
||||||
"friendlyName": "Level 3",
|
"friendlyName": "Level 3",
|
||||||
"description": "100% of the non-essential item pool is replaced with bee traps, of which 50% could be single bees.",
|
"description": "75% of rupees, bombs and arrows are replaced with bees, of which 80% are traps and 20% single bees",
|
||||||
"defaultValue": 3
|
"defaultValue": 3
|
||||||
},
|
},
|
||||||
"4": {
|
"4": {
|
||||||
"keyString": "beemizer.4",
|
"keyString": "beemizer.4",
|
||||||
"friendlyName": "Level 4",
|
"friendlyName": "Level 4",
|
||||||
"description": "100% of the non-essential item pool is replaced with bee traps.",
|
"description": "100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees",
|
||||||
"defaultValue": 4
|
"defaultValue": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,19 +1282,19 @@
|
||||||
"description": "No items are moved",
|
"description": "No items are moved",
|
||||||
"defaultValue": 50
|
"defaultValue": 50
|
||||||
},
|
},
|
||||||
"1": {
|
"10": {
|
||||||
"keyString": "shop_shuffle_slots.10",
|
"keyString": "shop_shuffle_slots.10",
|
||||||
"friendlyName": "Level 1",
|
"friendlyName": "Level 1",
|
||||||
"description": "10 Items are moved into shops.",
|
"description": "10 Items are moved into shops.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"2": {
|
"20": {
|
||||||
"keyString": "shop_shuffle_slots.20",
|
"keyString": "shop_shuffle_slots.20",
|
||||||
"friendlyName": "Level 2",
|
"friendlyName": "Level 2",
|
||||||
"description": "20 Items are moved into shops.",
|
"description": "20 Items are moved into shops.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"3": {
|
"30": {
|
||||||
"keyString": "shop_shuffle_slots.30",
|
"keyString": "shop_shuffle_slots.30",
|
||||||
"friendlyName": "Level 3",
|
"friendlyName": "Level 3",
|
||||||
"description": "30 Items are moved into shops.",
|
"description": "30 Items are moved into shops.",
|
||||||
|
@ -1600,6 +1632,25 @@
|
||||||
"description": "Hide both of the above options",
|
"description": "Hide both of the above options",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"reduceflashing": {
|
||||||
|
"keyString": "rom.reduceflashing",
|
||||||
|
"friendlyName": "Full-Screen Flashing Effects",
|
||||||
|
"description": "Enable or disable full-screen flashing effects in game.",
|
||||||
|
"inputType": "range",
|
||||||
|
"subOptions": {
|
||||||
|
"on": {
|
||||||
|
"keyString": "rom.reduceflashing.on",
|
||||||
|
"friendlyName": "Disabled",
|
||||||
|
"description": "Disables flashing.",
|
||||||
|
"defaultValue": 50
|
||||||
|
},
|
||||||
|
"off": {
|
||||||
|
"keyString": "rom.reduceflashing.off",
|
||||||
|
"friendlyName": "Enabled",
|
||||||
|
"description": "Enables flashing.",
|
||||||
|
"defaultValue": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"quickswap": {
|
"quickswap": {
|
||||||
|
@ -1797,7 +1848,7 @@
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"puke": {
|
"puke": {
|
||||||
"keyString": "rom.ow_palettes.Puke",
|
"keyString": "rom.ow_palettes.puke",
|
||||||
"friendlyName": "Puke",
|
"friendlyName": "Puke",
|
||||||
"description": "No logic at all.",
|
"description": "No logic at all.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
|
@ -1859,7 +1910,7 @@
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"puke": {
|
"puke": {
|
||||||
"keyString": "rom.uw_palettes.Puke",
|
"keyString": "rom.uw_palettes.puke",
|
||||||
"friendlyName": "Puke",
|
"friendlyName": "Puke",
|
||||||
"description": "No logic at all.",
|
"description": "No logic at all.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
|
@ -1921,7 +1972,7 @@
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"puke": {
|
"puke": {
|
||||||
"keyString": "rom.hud_palettes.Puke",
|
"keyString": "rom.hud_palettes.puke",
|
||||||
"friendlyName": "Puke",
|
"friendlyName": "Puke",
|
||||||
"description": "No logic at all.",
|
"description": "No logic at all.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
|
@ -1983,7 +2034,7 @@
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"puke": {
|
"puke": {
|
||||||
"keyString": "rom.shield_palettes.Puke",
|
"keyString": "rom.shield_palettes.puke",
|
||||||
"friendlyName": "Puke",
|
"friendlyName": "Puke",
|
||||||
"description": "No logic at all.",
|
"description": "No logic at all.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
|
@ -2045,7 +2096,7 @@
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
},
|
},
|
||||||
"puke": {
|
"puke": {
|
||||||
"keyString": "rom.sword_palettes.Puke",
|
"keyString": "rom.sword_palettes.puke",
|
||||||
"friendlyName": "Puke",
|
"friendlyName": "Puke",
|
||||||
"description": "No logic at all.",
|
"description": "No logic at all.",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
|
|
|
@ -17,6 +17,11 @@
|
||||||
# To test if your yaml is valid or not, you can use this website:
|
# To test if your yaml is valid or not, you can use this website:
|
||||||
# http://www.yamllint.com/
|
# http://www.yamllint.com/
|
||||||
|
|
||||||
|
# For use with the weighted-settings page on the website. Changing this value will cause all users to be prompted
|
||||||
|
# to update their settings. The version number should match the current released version number, and the revision
|
||||||
|
# should be updated manually by whoever edits this file.
|
||||||
|
ws_version: 4.0.1 rev1
|
||||||
|
|
||||||
description: Template Name # Used to describe your yaml. Useful if you have multiple files
|
description: Template Name # Used to describe your yaml. Useful if you have multiple files
|
||||||
name: YourName # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit
|
name: YourName # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit
|
||||||
### Logic Section ###
|
### Logic Section ###
|
||||||
|
@ -97,6 +102,11 @@ goals:
|
||||||
ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon
|
ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon
|
||||||
local_ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon
|
local_ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon
|
||||||
ice_rod_hunt: 0 # You start with everything needed to 216 the seed. Find the Ice rod, then kill Trinexx at Turtle rock.
|
ice_rod_hunt: 0 # You start with everything needed to 216 the seed. Find the Ice rod, then kill Trinexx at Turtle rock.
|
||||||
|
pyramid_open:
|
||||||
|
goal: 50 # Opens the pyramid if the goal requires you to kill Ganon, unless the goal is Slow Ganon or All Dungeons
|
||||||
|
auto: 0 # Same as Goal, but also opens when any non-dungeon entrance shuffle is used
|
||||||
|
yes: 0 # Pyramid hole is always open. Ganon's vulnerable condition is still required before he can he hurt
|
||||||
|
no: 0 # Pyramid hole is always closed until you defeat Agahnim atop Ganon's Tower
|
||||||
triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces.
|
triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces.
|
||||||
extra: 0 # available = triforce_pieces_extra + triforce_pieces_required
|
extra: 0 # available = triforce_pieces_extra + triforce_pieces_required
|
||||||
percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required
|
percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required
|
||||||
|
@ -218,10 +228,10 @@ pot_shuffle:
|
||||||
### End of Enemizer Section ###
|
### End of Enemizer Section ###
|
||||||
beemizer: # Remove items from the global item pool and replace them with single bees and bee traps
|
beemizer: # Remove items from the global item pool and replace them with single bees and bee traps
|
||||||
0: 50 # No bee traps are placed
|
0: 50 # No bee traps are placed
|
||||||
1: 0 # 25% of the non-essential item pool is replaced with bee traps
|
1: 0 # 25% of rupees, bombs and arrows are replaced with bees, of which 60% are traps and 40% single bees
|
||||||
2: 0 # 60% of the non-essential item pool is replaced with bee traps, of which 20% could be single bees
|
2: 0 # 50% of rupees, bombs and arrows are replaced with bees, of which 70% are traps and 30% single bees
|
||||||
3: 0 # 100% of the non-essential item pool is replaced with bee traps, of which 50% could be single bees
|
3: 0 # 75% of rupees, bombs and arrows are replaced with bees, of which 80% are traps and 20% single bees
|
||||||
4: 0 # 100% of the non-essential item pool is replaced with bee traps
|
4: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees
|
||||||
### Shop Settings ###
|
### Shop Settings ###
|
||||||
shop_shuffle_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
|
shop_shuffle_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
|
||||||
0: 50
|
0: 50
|
||||||
|
@ -353,6 +363,9 @@ rom:
|
||||||
quickswap: # Enable switching items by pressing the L+R shoulder buttons
|
quickswap: # Enable switching items by pressing the L+R shoulder buttons
|
||||||
on: 50
|
on: 50
|
||||||
off: 0
|
off: 0
|
||||||
|
reduceflashing: # Reduces instances of flashing such as lightning attacks, weather, ether and more.
|
||||||
|
on: 50
|
||||||
|
off: 0
|
||||||
menuspeed: # Controls how fast the item menu opens and closes
|
menuspeed: # Controls how fast the item menu opens and closes
|
||||||
normal: 50
|
normal: 50
|
||||||
instant: 0
|
instant: 0
|
||||||
|
|
|
@ -14,6 +14,17 @@ html{
|
||||||
color: #eeffeb;
|
color: #eeffeb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#user-warning{
|
||||||
|
display: none;
|
||||||
|
width: calc(100% - 8px);
|
||||||
|
background-color: #ffe86b;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #000000;
|
||||||
|
padding: 4px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
#weighted-settings code{
|
#weighted-settings code{
|
||||||
background-color: #d9cd8e;
|
background-color: #d9cd8e;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends 'tablepage.html' %}
|
{% extends 'tablepage.html' %}
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<title>Multiworld Tracker for Room {{ room.id }}</title>
|
<title>Multiworld Tracker</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ static_autoversion("styles/tracker.css") }}"/>
|
<link rel="stylesheet" type="text/css" href="{{ static_autoversion("styles/tracker.css") }}"/>
|
||||||
<script type="application/ecmascript" src="{{ static_autoversion("assets/jquery.scrollsync.js") }}"></script>
|
<script type="application/ecmascript" src="{{ static_autoversion("assets/jquery.scrollsync.js") }}"></script>
|
||||||
<script type="application/ecmascript" src="{{ static_autoversion("assets/tracker.js") }}"></script>
|
<script type="application/ecmascript" src="{{ static_autoversion("assets/tracker.js") }}"></script>
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for team, hints in hints.items() %}
|
{% for team, hints in hints.items() %}
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<table class="table non-unique-item-table">
|
<table class="table non-unique-item-table" data-order='[[5, "asc"], [0, "asc"]]'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Finder</th>
|
<th>Finder</th>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% include 'header/grassHeader.html' %}
|
{% include 'header/grassHeader.html' %}
|
||||||
<div id="weighted-settings">
|
<div id="weighted-settings">
|
||||||
|
<header id="user-warning"></header>
|
||||||
<h1>Weighted Settings</h1>
|
<h1>Weighted Settings</h1>
|
||||||
<div id="instructions">
|
<div id="instructions">
|
||||||
This page is used to configure your weighted settings. You have three presets you can control, which
|
This page is used to configure your weighted settings. You have three presets you can control, which
|
||||||
|
|
|
@ -13,7 +13,7 @@ from Utils import Hint
|
||||||
|
|
||||||
|
|
||||||
def get_id(item_name):
|
def get_id(item_name):
|
||||||
return Items.item_table[item_name][3]
|
return Items.item_table[item_name][2]
|
||||||
|
|
||||||
|
|
||||||
app.jinja_env.filters["location_name"] = lambda location: Regions.lookup_id_to_name.get(location, location)
|
app.jinja_env.filters["location_name"] = lambda location: Regions.lookup_id_to_name.get(location, location)
|
||||||
|
@ -233,9 +233,9 @@ for item_name, data in Items.item_table.items():
|
||||||
if "Key" in item_name:
|
if "Key" in item_name:
|
||||||
area = item_name.split("(")[1][:-1]
|
area = item_name.split("(")[1][:-1]
|
||||||
if "Small" in item_name:
|
if "Small" in item_name:
|
||||||
small_key_ids[area] = data[3]
|
small_key_ids[area] = data[2]
|
||||||
else:
|
else:
|
||||||
big_key_ids[area] = data[3]
|
big_key_ids[area] = data[2]
|
||||||
|
|
||||||
from MultiServer import get_item_name_from_id
|
from MultiServer import get_item_name_from_id
|
||||||
|
|
||||||
|
|
17
WebUI.py
17
WebUI.py
|
@ -51,31 +51,36 @@ class WebUiClient(Node, logging.Handler):
|
||||||
def poll_for_server_ip(self):
|
def poll_for_server_ip(self):
|
||||||
self.broadcast_all(self.build_message('serverAddress', {}))
|
self.broadcast_all(self.build_message('serverAddress', {}))
|
||||||
|
|
||||||
def notify_item_sent(self, finder, recipient, item, location, i_am_finder: bool, i_am_recipient: bool):
|
def notify_item_sent(self, finder, recipient, item, location, i_am_finder: bool, i_am_recipient: bool,
|
||||||
|
item_is_unique: bool = False):
|
||||||
self.broadcast_all(self.build_message('itemSent', {
|
self.broadcast_all(self.build_message('itemSent', {
|
||||||
'finder': finder,
|
'finder': finder,
|
||||||
'recipient': recipient,
|
'recipient': recipient,
|
||||||
'item': item,
|
'item': item,
|
||||||
'location': location,
|
'location': location,
|
||||||
'iAmFinder': 1 if i_am_finder else 0,
|
'iAmFinder': int(i_am_finder),
|
||||||
'iAmRecipient': 1 if i_am_recipient else 0,
|
'iAmRecipient': int(i_am_recipient),
|
||||||
|
'itemIsUnique': int(item_is_unique),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
def notify_item_found(self, finder: str, item: str, location: str, i_am_finder: bool):
|
def notify_item_found(self, finder: str, item: str, location: str, i_am_finder: bool, item_is_unique: bool = False):
|
||||||
self.broadcast_all(self.build_message('itemFound', {
|
self.broadcast_all(self.build_message('itemFound', {
|
||||||
'finder': finder,
|
'finder': finder,
|
||||||
'item': item,
|
'item': item,
|
||||||
'location': location,
|
'location': location,
|
||||||
'iAmFinder': 1 if i_am_finder else 0,
|
'iAmFinder': int(i_am_finder),
|
||||||
|
'itemIsUnique': int(item_is_unique),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
def notify_item_received(self, finder: str, item: str, location: str, item_index: int, queue_length: int):
|
def notify_item_received(self, finder: str, item: str, location: str, item_index: int, queue_length: int,
|
||||||
|
item_is_unique: bool = False):
|
||||||
self.broadcast_all(self.build_message('itemReceived', {
|
self.broadcast_all(self.build_message('itemReceived', {
|
||||||
'finder': finder,
|
'finder': finder,
|
||||||
'item': item,
|
'item': item,
|
||||||
'location': location,
|
'location': location,
|
||||||
'itemIndex': item_index,
|
'itemIndex': item_index,
|
||||||
'queueLength': queue_length,
|
'queueLength': queue_length,
|
||||||
|
'itemIsUnique': int(item_is_unique),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
def send_hint(self, finder, recipient, item, location, found, i_am_finder: bool, i_am_recipient: bool,
|
def send_hint(self, finder, recipient, item, location, found, i_am_finder: bool, i_am_recipient: bool,
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -10,38 +10,39 @@
|
||||||
"author": "LegendaryLinux",
|
"author": "LegendaryLinux",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
"@fortawesome/fontawesome-svg-core": "^1.2.34",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
"@fortawesome/free-solid-svg-icons": "^5.15.2",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.10",
|
"@fortawesome/react-fontawesome": "^0.1.14",
|
||||||
|
"crypto-browserify": "^3.12.0",
|
||||||
"crypto-js": "^4.0.0",
|
"crypto-js": "^4.0.0",
|
||||||
"css-loader": "^3.5.3",
|
"css-loader": "^5.0.1",
|
||||||
"lodash-es": "^4.17.15",
|
"lodash-es": "^4.17.20",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-redux": "^7.2.1",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-devtools-extension": "^2.13.8",
|
"redux-devtools-extension": "^2.13.8",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^10.1.1",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^2.0.0",
|
||||||
"webpack-cli": "^3.3.11"
|
"webpack-cli": "^4.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.11.4",
|
"@babel/core": "^7.12.13",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
"@babel/plugin-proposal-class-properties": "^7.12.13",
|
||||||
"@babel/preset-env": "^7.11.0",
|
"@babel/preset-env": "^7.12.13",
|
||||||
"@babel/preset-react": "^7.10.4",
|
"@babel/preset-react": "^7.12.13",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-loader": "^8.1.0",
|
"babel-loader": "^8.2.2",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^7.19.0",
|
||||||
"eslint-config-airbnb": "^18.2.0",
|
"eslint-config-airbnb": "^18.2.1",
|
||||||
"eslint-plugin-import": "^2.22.0",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
"eslint-plugin-jsx-a11y": "^6.3.1",
|
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||||
"eslint-plugin-react": "^7.20.6",
|
"eslint-plugin-react": "^7.22.0",
|
||||||
"eslint-plugin-react-hooks": "^2.5.1",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.2.0",
|
||||||
"node-sass": "^4.14.1",
|
"node-sass": "^5.0.0",
|
||||||
"webpack": "^4.44.1"
|
"webpack": "^5.20.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,7 @@ const finderSpan = (finder, possessive = false, ownItem = false) => (
|
||||||
const recipientSpan = (recipient, possessive = false, ownItem = false) => (
|
const recipientSpan = (recipient, possessive = false, ownItem = false) => (
|
||||||
<span className={ `recipient-span ${ownItem ? 'mine' : null}` }>{recipient}{possessive ? "'s" : null}</span>
|
<span className={ `recipient-span ${ownItem ? 'mine' : null}` }>{recipient}{possessive ? "'s" : null}</span>
|
||||||
);
|
);
|
||||||
const itemSpan = (item) => <span className="item-span">{item}</span>;
|
const itemSpan = (item, unique) => <span className={ `item-span ${unique ? 'unique' : ''}` }>{item}</span>;
|
||||||
const locationSpan = (location) => <span className="location-span">{location}</span>;
|
const locationSpan = (location) => <span className="location-span">{location}</span>;
|
||||||
const entranceSpan = (entrance) => <span className="entrance-span">{entrance}</span>;
|
const entranceSpan = (entrance) => <span className="entrance-span">{entrance}</span>;
|
||||||
|
|
||||||
|
@ -20,34 +20,34 @@ class MonitorTools {
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Sent an item to another player */
|
/** Sent an item to another player */
|
||||||
static sentItem = (finder, recipient, item, location, iAmFinder = false, iAmRecipient = false) => (
|
static sentItem = (finder, recipient, item, location, iAmFinder = false, iAmRecipient = false, unique = false) => (
|
||||||
<div
|
<div
|
||||||
key={ `${md5(finder + recipient + item + location)}${Math.floor((Math.random() * 1000000))}` }
|
key={ `${md5(finder + recipient + item + location)}${Math.floor((Math.random() * 1000000))}` }
|
||||||
className={ (iAmFinder || iAmRecipient) ? 'relevant' : null }
|
className={ (iAmFinder || iAmRecipient) ? 'relevant' : null }
|
||||||
>
|
>
|
||||||
{finderSpan(finder, false, iAmFinder)} found {recipientSpan(recipient, true, iAmRecipient)}
|
{finderSpan(finder, false, iAmFinder)} found {recipientSpan(recipient, true, iAmRecipient)}
|
||||||
{itemSpan(item)} at {locationSpan(location)}
|
{itemSpan(item, unique)} at {locationSpan(location)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Received item from another player */
|
/** Received item from another player */
|
||||||
static receivedItem = (finder, item, location, itemIndex, queueLength) => (
|
static receivedItem = (finder, item, location, itemIndex, queueLength, unique = false) => (
|
||||||
<div
|
<div
|
||||||
key={ `${md5(finder + item + location)}${Math.floor((Math.random() * 1000000))}` }
|
key={ `${md5(finder + item + location)}${Math.floor((Math.random() * 1000000))}` }
|
||||||
className="relevant"
|
className="relevant"
|
||||||
>
|
>
|
||||||
({itemIndex}/{queueLength}) {finderSpan(finder, false)} found your
|
({itemIndex}/{queueLength}) {finderSpan(finder, false)} found your
|
||||||
{itemSpan(item)} at {locationSpan(location)}
|
{itemSpan(item, unique)} at {locationSpan(location)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Player found their own item (local or remote player) */
|
/** Player found their own item (local or remote player) */
|
||||||
static foundItem = (finder, item, location, iAmFinder = false) => (
|
static foundItem = (finder, item, location, iAmFinder = false, unique = false) => (
|
||||||
<div
|
<div
|
||||||
key={ `${md5(finder + item + location)}${Math.floor((Math.random() * 1000000))}` }
|
key={ `${md5(finder + item + location)}${Math.floor((Math.random() * 1000000))}` }
|
||||||
className={ iAmFinder ? 'relevant' : null }
|
className={ iAmFinder ? 'relevant' : null }
|
||||||
>
|
>
|
||||||
{finderSpan(finder, false, iAmFinder)} found their own {itemSpan(item)} at {locationSpan(location)}
|
{finderSpan(finder, false, iAmFinder)} found their own {itemSpan(item, unique)} at {locationSpan(location)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -44,15 +44,16 @@ class WebSocketUtils {
|
||||||
case 'itemSent':
|
case 'itemSent':
|
||||||
return appendMessage(MonitorTools.sentItem(data.content.finder, data.content.recipient,
|
return appendMessage(MonitorTools.sentItem(data.content.finder, data.content.recipient,
|
||||||
data.content.item, data.content.location, parseInt(data.content.iAmFinder, 10) === 1,
|
data.content.item, data.content.location, parseInt(data.content.iAmFinder, 10) === 1,
|
||||||
parseInt(data.content.iAmRecipient, 10) === 1));
|
parseInt(data.content.iAmRecipient, 10) === 1, parseInt(data.content.itemIsUnique, 10) === 1));
|
||||||
|
|
||||||
case 'itemReceived':
|
case 'itemReceived':
|
||||||
return appendMessage(MonitorTools.receivedItem(data.content.finder, data.content.item,
|
return appendMessage(MonitorTools.receivedItem(data.content.finder, data.content.item,
|
||||||
data.content.location, data.content.itemIndex, data.content.queueLength));
|
data.content.location, data.content.itemIndex, data.content.queueLength,
|
||||||
|
parseInt(data.content.itemIsUnique, 10) === 1));
|
||||||
|
|
||||||
case 'itemFound':
|
case 'itemFound':
|
||||||
return appendMessage(MonitorTools.foundItem(data.content.finder, data.content.item, data.content.location,
|
return appendMessage(MonitorTools.foundItem(data.content.finder, data.content.item, data.content.location,
|
||||||
parseInt(data.content.iAmFinder, 10) === 1));
|
parseInt(data.content.iAmFinder, 10) === 1, parseInt(data.content.itemIsUnique, 10) === 1));
|
||||||
|
|
||||||
case 'hint':
|
case 'hint':
|
||||||
return appendMessage(MonitorTools.hintMessage(data.content.finder, data.content.recipient,
|
return appendMessage(MonitorTools.hintMessage(data.content.finder, data.content.recipient,
|
||||||
|
|
|
@ -25,9 +25,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-span{ color: #67e9ff; }
|
.item-span{
|
||||||
|
color: #67e9ff;
|
||||||
|
|
||||||
|
&.unique{
|
||||||
|
color: #ff884e;
|
||||||
|
text-shadow: #000000 2px 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.location-span{ color: #f5e63c; }
|
.location-span{ color: #f5e63c; }
|
||||||
.entrance-span{ color: #73ae38 }
|
.entrance-span{ color: #73ae38; }
|
||||||
.finder-span{ color: #f96cb8; }
|
.finder-span{ color: #f96cb8; }
|
||||||
.recipient-span{ color: #9b8aff; }
|
.recipient-span{ color: #9b8aff; }
|
||||||
.mine{ color: #ffa500; }
|
.mine{ color: #ffa500; }
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = {
|
||||||
{
|
{
|
||||||
test: /\.(js|jsx|es6)$/,
|
test: /\.(js|jsx|es6)$/,
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
query: {
|
options: {
|
||||||
compact: true,
|
compact: true,
|
||||||
minified: true,
|
minified: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = {
|
||||||
{
|
{
|
||||||
test: /\.(js|jsx|es6)$/,
|
test: /\.(js|jsx|es6)$/,
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
query: {
|
options: {
|
||||||
compact: false,
|
compact: false,
|
||||||
minified: false,
|
minified: false,
|
||||||
},
|
},
|
||||||
|
@ -42,5 +42,4 @@ module.exports = {
|
||||||
publicPath: '/',
|
publicPath: '/',
|
||||||
filename: '[name].bundle.js',
|
filename: '[name].bundle.js',
|
||||||
},
|
},
|
||||||
devtool: 'source-map',
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,10 +20,11 @@
|
||||||
description: Template Name # Used to describe your yaml. Useful if you have multiple files
|
description: Template Name # Used to describe your yaml. Useful if you have multiple files
|
||||||
name: YourName # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit
|
name: YourName # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit
|
||||||
### Logic Section ###
|
### Logic Section ###
|
||||||
|
# Warning: overworld_glitches is not available and minor_glitches is only partially implemented on the door-rando version
|
||||||
glitches_required: # Determine the logic required to complete the seed
|
glitches_required: # Determine the logic required to complete the seed
|
||||||
none: 50 # No glitches required
|
none: 50 # No glitches required
|
||||||
minor_glitches: 0 # Puts fake flipper, waterwalk, super bunny shenanigans, and etc into logic
|
minor_glitches: 0 # Puts fake flipper, waterwalk, super bunny shenanigans, and etc into logic
|
||||||
overworld_glitches: 0 # Assumes the player has knowledge of both overworld major glitches (boots clips, mirror clips) and minor glitches (fake flipper, super bunny shenanigans, water walk and etc.)
|
overworld_glitches: 0 # Assumes the player has knowledge of both overworld major glitches (boots clips, mirror clips) and minor glitches
|
||||||
no_logic: 0 # Your own items are placed with no regard to any logic; such as your Fire Rod can be on your Trinexx.
|
no_logic: 0 # Your own items are placed with no regard to any logic; such as your Fire Rod can be on your Trinexx.
|
||||||
# Other players items are placed into your world under OWG logic
|
# Other players items are placed into your world under OWG logic
|
||||||
dark_room_logic: # Logic for unlit dark rooms
|
dark_room_logic: # Logic for unlit dark rooms
|
||||||
|
@ -86,9 +87,12 @@ entrance_shuffle: # Documentation: https://alttpr.com/en/options#entrance_shuffl
|
||||||
full: 0 # Less strict than restricted
|
full: 0 # Less strict than restricted
|
||||||
crossed: 0 # Less strict than full
|
crossed: 0 # Less strict than full
|
||||||
insanity: 0 # Very few grouping rules. Good luck
|
insanity: 0 # Very few grouping rules. Good luck
|
||||||
|
# you can also define entrance shuffle seed, like so:
|
||||||
|
crossed-1000: 0 # using this method, you can have the same layout as another player and share entrance information
|
||||||
|
# however, many other settings like logic, world state, retro etc. may affect the shuffle result as well.
|
||||||
goals:
|
goals:
|
||||||
ganon: 50 # Climb GT, defeat Agahnim 2, and then kill Ganon
|
ganon: 50 # Climb GT, defeat Agahnim 2, and then kill Ganon
|
||||||
fast_ganon: 0 # Only killing Ganon is required. The hole is always open. However, items may still be placed in GT
|
fast_ganon: 0 # Only killing Ganon is required. However, items may still be placed in GT
|
||||||
dungeons: 0 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2)
|
dungeons: 0 # Defeat the boss of all dungeons, including Agahnim's tower and GT (Aga 2)
|
||||||
pedestal: 0 # Pull the Triforce from the Master Sword pedestal
|
pedestal: 0 # Pull the Triforce from the Master Sword pedestal
|
||||||
ganon_pedestal: 0 # Pull the Master Sword pedestal, then kill Ganon
|
ganon_pedestal: 0 # Pull the Master Sword pedestal, then kill Ganon
|
||||||
|
@ -97,6 +101,11 @@ goals:
|
||||||
ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon
|
ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout the worlds, then kill Ganon
|
||||||
local_ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon
|
local_ganon_triforce_hunt: 0 # Collect 20 of 30 Triforce pieces spread throughout your world, then kill Ganon
|
||||||
ice_rod_hunt: 0 # You start with everything needed to 216 the seed. Find the Ice rod, then kill Trinexx at Turtle rock.
|
ice_rod_hunt: 0 # You start with everything needed to 216 the seed. Find the Ice rod, then kill Trinexx at Turtle rock.
|
||||||
|
open_pyramid:
|
||||||
|
goal: 50 # Opens the pyramid if the goal requires you to kill Ganon, unless the goal is Slow Ganon or All Dungeons
|
||||||
|
auto: 0 # Same as Goal, but also is closed if holes are shuffled and ganon is part of the shuffle pool
|
||||||
|
yes: 0 # Pyramid hole is always open. Ganon's vulnerable condition is still required before he can he hurt
|
||||||
|
no: 0 # Pyramid hole is always closed until you defeat Agahnim atop Ganon's Tower
|
||||||
triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces.
|
triforce_pieces_mode: #Determine how to calculate the extra available triforce pieces.
|
||||||
extra: 0 # available = triforce_pieces_extra + triforce_pieces_required
|
extra: 0 # available = triforce_pieces_extra + triforce_pieces_required
|
||||||
percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required
|
percentage: 0 # available = (triforce_pieces_percentage /100) * triforce_pieces_required
|
||||||
|
@ -216,12 +225,12 @@ pot_shuffle:
|
||||||
'on': 0 # Keys, items, and buttons hidden under pots in dungeons are shuffled with other pots in their supertile
|
'on': 0 # Keys, items, and buttons hidden under pots in dungeons are shuffled with other pots in their supertile
|
||||||
'off': 50 # Default pot item locations
|
'off': 50 # Default pot item locations
|
||||||
### End of Enemizer Section ###
|
### End of Enemizer Section ###
|
||||||
beemizer: # Remove items from the global item pool and replace them with single bees and bee traps
|
beemizer: # Remove items from the global item pool and replace them with single bees (fill bottles) and bee traps
|
||||||
0: 50 # No bee traps are placed
|
0: 50 # No bee traps are placed
|
||||||
1: 0 # 25% of the non-essential item pool is replaced with bee traps
|
1: 0 # 25% of rupees, bombs and arrows are replaced with bees, of which 60% are traps and 40% single bees
|
||||||
2: 0 # 60% of the non-essential item pool is replaced with bee traps, of which 20% could be single bees
|
2: 0 # 50% of rupees, bombs and arrows are replaced with bees, of which 70% are traps and 30% single bees
|
||||||
3: 0 # 100% of the non-essential item pool is replaced with bee traps, of which 50% could be single bees
|
3: 0 # 75% of rupees, bombs and arrows are replaced with bees, of which 80% are traps and 20% single bees
|
||||||
4: 0 # 100% of the non-essential item pool is replaced with bee traps
|
4: 0 # 100% of rupees, bombs and arrows are replaced with bees, of which 90% are traps and 10% single bees
|
||||||
### Shop Settings ###
|
### Shop Settings ###
|
||||||
shop_shuffle_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
|
shop_shuffle_slots: # Maximum amount of shop slots to be filled with regular item pool items (such as Moon Pearl)
|
||||||
0: 50
|
0: 50
|
||||||
|
@ -243,8 +252,8 @@ shop_shuffle:
|
||||||
### End of Shop Section ###
|
### End of Shop Section ###
|
||||||
shuffle_prizes: # aka drops
|
shuffle_prizes: # aka drops
|
||||||
none: 0 # do not shuffle prize packs
|
none: 0 # do not shuffle prize packs
|
||||||
g: 50 # shuffle "general" price packs, as in enemy, tree pull, dig etc.
|
g: 50 # shuffle "general" prize packs, as in enemy, tree pull, dig etc.
|
||||||
b: 0 # shuffle "bonk" price packs
|
b: 0 # shuffle "bonk" prize packs
|
||||||
bg: 0 # shuffle both
|
bg: 0 # shuffle both
|
||||||
timer:
|
timer:
|
||||||
none: 50 # No timer will be displayed.
|
none: 50 # No timer will be displayed.
|
||||||
|
@ -317,6 +326,13 @@ linked_options:
|
||||||
hard: 1
|
hard: 1
|
||||||
expert: 1
|
expert: 1
|
||||||
percentage: 0 # Set this to the percentage chance you want enemizer
|
percentage: 0 # Set this to the percentage chance you want enemizer
|
||||||
|
# triggers that replace options upon rolling certain options
|
||||||
|
triggers:
|
||||||
|
- option_name: enemy_damage # targets enemy_damage
|
||||||
|
option_result: shuffled # if it rolls shuffled
|
||||||
|
percentage: 0 # AND has a 0 percent chance (meaning this is default disabled, just to show how it works)
|
||||||
|
options: # then inserts these options
|
||||||
|
swords: assured
|
||||||
### door rando only options ###
|
### door rando only options ###
|
||||||
door_shuffle: # Only available if the host uses the doors branch, it is ignored otherwise
|
door_shuffle: # Only available if the host uses the doors branch, it is ignored otherwise
|
||||||
vanilla: 50 # Everything should be like in vanilla
|
vanilla: 50 # Everything should be like in vanilla
|
||||||
|
@ -393,6 +409,9 @@ rom:
|
||||||
hide_goal: 50 # hide counter until a piece is collected or speaking to Murahalda
|
hide_goal: 50 # hide counter until a piece is collected or speaking to Murahalda
|
||||||
hide_required: 0 # Always visible, but required amount is invisible until determined by Murahalda
|
hide_required: 0 # Always visible, but required amount is invisible until determined by Murahalda
|
||||||
hide_both: 0 # Hide both under above circumstances
|
hide_both: 0 # Hide both under above circumstances
|
||||||
|
reduceflashing: # Reduces instances of flashing such as lightning attacks, weather, ether and more.
|
||||||
|
on: 50
|
||||||
|
off: 0
|
||||||
menuspeed: # Controls how fast the item menu opens and closes
|
menuspeed: # Controls how fast the item menu opens and closes
|
||||||
normal: 50
|
normal: 50
|
||||||
instant: 0
|
instant: 0
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
colorama>=0.4.4
|
colorama>=0.4.4
|
||||||
websockets>=8.1
|
websockets>=8.1
|
||||||
PyYAML>=5.4
|
PyYAML>=5.4.1
|
||||||
fuzzywuzzy>=0.18.0
|
fuzzywuzzy>=0.18.0
|
||||||
bsdiff4>=1.2.0
|
bsdiff4>=1.2.0
|
||||||
prompt_toolkit>=3.0.10
|
prompt_toolkit>=3.0.16
|
||||||
appdirs>=1.4.4
|
appdirs>=1.4.4
|
||||||
maseya-z3pr>=1.0.0rc1
|
maseya-z3pr>=1.0.0rc1
|
||||||
xxtea>=2.0.0.post0
|
xxtea>=2.0.0.post0
|
||||||
|
|
7
setup.py
7
setup.py
|
@ -48,8 +48,8 @@ def manifest_creation():
|
||||||
path = os.path.join(dirpath, filename)
|
path = os.path.join(dirpath, filename)
|
||||||
hashes[os.path.relpath(path, start=buildfolder)] = pool.submit(_threaded_hash, path)
|
hashes[os.path.relpath(path, start=buildfolder)] = pool.submit(_threaded_hash, path)
|
||||||
import json
|
import json
|
||||||
manifest = {"buildtime": buildtime.isoformat(sep=" ", timespec="seconds")}
|
manifest = {"buildtime": buildtime.isoformat(sep=" ", timespec="seconds"),
|
||||||
manifest["hashes"] = {path: hash.result() for path, hash in hashes.items()}
|
"hashes": {path: hash.result() for path, hash in hashes.items()}}
|
||||||
json.dump(manifest, open(manifestpath, "wt"), indent=4)
|
json.dump(manifest, open(manifestpath, "wt"), indent=4)
|
||||||
print("Created Manifest")
|
print("Created Manifest")
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ scripts = {"MultiClient.py": "BerserkerMultiClient",
|
||||||
"MultiMystery.py": "BerserkerMultiMystery",
|
"MultiMystery.py": "BerserkerMultiMystery",
|
||||||
"MultiServer.py": "BerserkerMultiServer",
|
"MultiServer.py": "BerserkerMultiServer",
|
||||||
"gui.py": "BerserkerMultiCreator",
|
"gui.py": "BerserkerMultiCreator",
|
||||||
"Mystery.py": "BerserkerMystery"}
|
"Mystery.py": "BerserkerMystery",
|
||||||
|
"Adjuster.py": "BerserkerLttPAdjuster"}
|
||||||
|
|
||||||
exes = []
|
exes = []
|
||||||
|
|
||||||
|
|
|
@ -19,55 +19,70 @@ class TestBase(unittest.TestCase):
|
||||||
self._state_cache[self.world, tuple(items)] = state
|
self._state_cache[self.world, tuple(items)] = state
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
def get_path(self, state, region):
|
||||||
|
def flist_to_iter(node):
|
||||||
|
while node:
|
||||||
|
value, node = node
|
||||||
|
yield value
|
||||||
|
|
||||||
|
from itertools import zip_longest
|
||||||
|
reversed_path_as_flist = state.path.get(region, (region, None))
|
||||||
|
string_path_flat = reversed(list(map(str, flist_to_iter(reversed_path_as_flist))))
|
||||||
|
# Now we combine the flat string list into (region, exit) pairs
|
||||||
|
pathsiter = iter(string_path_flat)
|
||||||
|
pathpairs = zip_longest(pathsiter, pathsiter)
|
||||||
|
return list(pathpairs)
|
||||||
|
|
||||||
def run_location_tests(self, access_pool):
|
def run_location_tests(self, access_pool):
|
||||||
for location, access, *item_pool in access_pool:
|
for i, (location, access, *item_pool) in enumerate(access_pool):
|
||||||
items = item_pool[0]
|
items = item_pool[0]
|
||||||
all_except = item_pool[1] if len(item_pool) > 1 else None
|
all_except = item_pool[1] if len(item_pool) > 1 else None
|
||||||
with self.subTest(msg="Reach Location", location=location, access=access, items=items, all_except=all_except):
|
state = self._get_items(item_pool, all_except)
|
||||||
if all_except and len(all_except) > 0:
|
path = self.get_path(state, self.world.get_location(location, 1).parent_region)
|
||||||
items = self.world.itempool[:]
|
with self.subTest(msg="Reach Location", location=location, access=access, items=items,
|
||||||
items = [item for item in items if item.name not in all_except and not ("Bottle" in item.name and "AnyBottle" in all_except)]
|
all_except=all_except, path=path, entry=i):
|
||||||
items.extend(ItemFactory(item_pool[0], 1))
|
|
||||||
else:
|
|
||||||
items = ItemFactory(items, 1)
|
|
||||||
state = self.get_state(items)
|
|
||||||
|
|
||||||
self.assertEqual(self.world.get_location(location, 1).can_reach(state), access)
|
self.assertEqual(self.world.get_location(location, 1).can_reach(state), access)
|
||||||
|
|
||||||
|
# check for partial solution
|
||||||
#check for partial solution
|
if not all_except and access: # we are not supposed to be able to reach location with partial inventory
|
||||||
if not all_except and access:# we are not supposed to be able to reach location with partial inventory
|
|
||||||
for missing_item in item_pool[0]:
|
for missing_item in item_pool[0]:
|
||||||
with self.subTest(msg="Location reachable without required item", location=location,
|
with self.subTest(msg="Location reachable without required item", location=location,
|
||||||
items=item_pool[0], missing_item=missing_item):
|
items=item_pool[0], missing_item=missing_item, entry=i):
|
||||||
new_items = item_pool[0].copy()
|
state = self._get_items_partial(item_pool, missing_item)
|
||||||
new_items.remove(missing_item)
|
|
||||||
items = ItemFactory(new_items, 1)
|
|
||||||
state = self.get_state(items)
|
|
||||||
self.assertEqual(self.world.get_location(location, 1).can_reach(state), False)
|
self.assertEqual(self.world.get_location(location, 1).can_reach(state), False)
|
||||||
|
|
||||||
def run_entrance_tests(self, access_pool):
|
def run_entrance_tests(self, access_pool):
|
||||||
for entrance, access, *item_pool in access_pool:
|
for i, (entrance, access, *item_pool) in enumerate(access_pool):
|
||||||
items = item_pool[0]
|
items = item_pool[0]
|
||||||
all_except = item_pool[1] if len(item_pool) > 1 else None
|
all_except = item_pool[1] if len(item_pool) > 1 else None
|
||||||
with self.subTest(msg="Reach Entrance", entrance=entrance, access=access, items=items, all_except=all_except):
|
state = self._get_items(item_pool, all_except)
|
||||||
if all_except and len(all_except) > 0:
|
path = self.get_path(state, self.world.get_entrance(entrance, 1).parent_region)
|
||||||
items = self.world.itempool[:]
|
with self.subTest(msg="Reach Entrance", entrance=entrance, access=access, items=items,
|
||||||
items = [item for item in items if item.name not in all_except and not ("Bottle" in item.name and "AnyBottle" in all_except)]
|
all_except=all_except, path=path, entry=i):
|
||||||
items.extend(ItemFactory(item_pool[0], 1))
|
|
||||||
else:
|
|
||||||
items = ItemFactory(items, 1)
|
|
||||||
state = self.get_state(items)
|
|
||||||
|
|
||||||
self.assertEqual(self.world.get_entrance(entrance, 1).can_reach(state), access)
|
self.assertEqual(self.world.get_entrance(entrance, 1).can_reach(state), access)
|
||||||
|
|
||||||
#check for partial solution
|
# check for partial solution
|
||||||
if not all_except and access:# we are not supposed to be able to reach location with partial inventory
|
if not all_except and access: # we are not supposed to be able to reach location with partial inventory
|
||||||
for missing_item in item_pool[0]:
|
for missing_item in item_pool[0]:
|
||||||
with self.subTest(msg="Entrance reachable without required item", entrance=entrance,
|
with self.subTest(msg="Entrance reachable without required item", entrance=entrance,
|
||||||
items=item_pool[0], missing_item=missing_item):
|
items=item_pool[0], missing_item=missing_item, entry=i):
|
||||||
|
state = self._get_items_partial(item_pool, missing_item)
|
||||||
|
self.assertEqual(self.world.get_entrance(entrance, 1).can_reach(state), False)
|
||||||
|
|
||||||
|
def _get_items(self, item_pool, all_except):
|
||||||
|
if all_except and len(all_except) > 0:
|
||||||
|
items = self.world.itempool[:]
|
||||||
|
items = [item for item in items if
|
||||||
|
item.name not in all_except and not ("Bottle" in item.name and "AnyBottle" in all_except)]
|
||||||
|
items.extend(ItemFactory(item_pool[0], 1))
|
||||||
|
else:
|
||||||
|
items = ItemFactory(item_pool[0], 1)
|
||||||
|
return self.get_state(items)
|
||||||
|
|
||||||
|
def _get_items_partial(self, item_pool, missing_item):
|
||||||
new_items = item_pool[0].copy()
|
new_items = item_pool[0].copy()
|
||||||
new_items.remove(missing_item)
|
new_items.remove(missing_item)
|
||||||
items = ItemFactory(new_items, 1)
|
items = ItemFactory(new_items, 1)
|
||||||
state = self.get_state(items)
|
return self.get_state(items)
|
||||||
self.assertEqual(self.world.get_entrance(entrance, 1).can_reach(state), False)
|
|
||||||
|
|
|
@ -97,16 +97,11 @@ class TestInvertedDarkWorld(TestInverted):
|
||||||
def testMireArea(self):
|
def testMireArea(self):
|
||||||
self.run_location_tests([
|
self.run_location_tests([
|
||||||
["Mire Shed - Left", False, []],
|
["Mire Shed - Left", False, []],
|
||||||
["Mire Shed - Left", False, [], ['Flute', 'Magic Mirror']],
|
["Mire Shed - Left", True, ['Flute']],
|
||||||
["Mire Shed - Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove']],
|
|
||||||
["Mire Shed - Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Mire Shed - Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1']],
|
|
||||||
["Mire Shed - Left", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
["Mire Shed - Left", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
||||||
|
|
||||||
["Mire Shed - Right", False, []],
|
["Mire Shed - Right", False, []],
|
||||||
["Mire Shed - Right", False, [], ['Flute', 'Magic Mirror']],
|
["Mire Shed - Right", True, ['Flute']],
|
||||||
["Mire Shed - Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove']],
|
|
||||||
["Mire Shed - Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Mire Shed - Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1']],
|
|
||||||
["Mire Shed - Right", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
["Mire Shed - Right", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
||||||
|
|
||||||
])
|
])
|
|
@ -9,16 +9,13 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Old Man", False, [], ['Progressive Glove', 'Flute']],
|
["Old Man", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Old Man", False, [], ['Lamp']],
|
["Old Man", False, [], ['Lamp']],
|
||||||
["Old Man", True, ['Progressive Glove', 'Lamp']],
|
["Old Man", True, ['Progressive Glove', 'Lamp']],
|
||||||
["Old Man", False, ['Flute', 'Lamp']],
|
["Old Man", True, ['Flute', 'Lamp']],
|
||||||
|
|
||||||
["Spectacle Rock Cave", False, []],
|
["Spectacle Rock Cave", False, []],
|
||||||
["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Flute']],
|
["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Spectacle Rock Cave", False, [], ['Lamp', 'Flute']],
|
["Spectacle Rock Cave", False, [], ['Lamp', 'Flute']],
|
||||||
["Spectacle Rock Cave", False, ['Flute', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Spectacle Rock Cave", False, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Spectacle Rock Cave", False, ['Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Spectacle Rock Cave", False, ['Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Spectacle Rock Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
["Spectacle Rock Cave", True, ['Flute']],
|
||||||
["Spectacle Rock Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
|
||||||
["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']],
|
["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -31,12 +28,10 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Spiral Cave", False, ['Progressive Glove'], ['Hookshot', 'Progressive Glove']],
|
["Spiral Cave", False, ['Progressive Glove'], ['Hookshot', 'Progressive Glove']],
|
||||||
["Spiral Cave", False, ['Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Spiral Cave", False, ['Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Spiral Cave", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Spiral Cave", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Spiral Cave", False, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
["Spiral Cave", True, ['Moon Pearl', 'Flute', 'Hookshot']],
|
||||||
["Spiral Cave", False, ['Flute', 'Hookshot', 'Moon Pearl']],
|
["Spiral Cave", True, ['Moon Pearl', 'Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Spiral Cave", True, ['Flute', 'Hookshot', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
["Spiral Cave", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Lamp']],
|
||||||
["Spiral Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hookshot']],
|
["Spiral Cave", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove']],
|
||||||
["Spiral Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
|
||||||
["Spiral Cave", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
|
||||||
|
|
||||||
["Paradox Cave Lower - Far Left", False, []],
|
["Paradox Cave Lower - Far Left", False, []],
|
||||||
["Paradox Cave Lower - Far Left", False, [], ['Moon Pearl']],
|
["Paradox Cave Lower - Far Left", False, [], ['Moon Pearl']],
|
||||||
|
@ -45,7 +40,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Lower - Far Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Far Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Far Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -57,7 +52,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Lower - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -69,7 +64,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Lower - Middle", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Middle", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Middle", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -81,7 +76,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Lower - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -93,7 +88,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Lower - Far Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Far Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Far Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -105,7 +100,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Upper - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Upper - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Upper - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -117,7 +112,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Paradox Cave Upper - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Upper - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Upper - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -127,7 +122,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Mimic Cave", False, [], ['Hammer']],
|
["Mimic Cave", False, [], ['Hammer']],
|
||||||
["Mimic Cave", False, [], ['Progressive Glove', 'Flute']],
|
["Mimic Cave", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Mimic Cave", False, [], ['Lamp', 'Flute']],
|
["Mimic Cave", False, [], ['Lamp', 'Flute']],
|
||||||
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot']],
|
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||||
["Mimic Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
["Mimic Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Mimic Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
["Mimic Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
||||||
|
@ -140,7 +135,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Ether Tablet", False, [], ['Hammer']],
|
["Ether Tablet", False, [], ['Hammer']],
|
||||||
["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||||
["Ether Tablet", False, [], ['Book of Mudora']],
|
["Ether Tablet", False, [], ['Book of Mudora']],
|
||||||
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Ether Tablet", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
|
@ -151,7 +146,7 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Spectacle Rock", False, [], ['Lamp', 'Flute']],
|
["Spectacle Rock", False, [], ['Lamp', 'Flute']],
|
||||||
["Spectacle Rock", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Spectacle Rock", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Spectacle Rock", False, [], ['Hammer']],
|
["Spectacle Rock", False, [], ['Hammer']],
|
||||||
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot']],
|
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||||
["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Spectacle Rock", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
["Spectacle Rock", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
||||||
|
@ -160,47 +155,38 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
def testEastDarkWorldDeathMountain(self):
|
def testEastDarkWorldDeathMountain(self):
|
||||||
self.run_location_tests([
|
self.run_location_tests([
|
||||||
["Superbunny Cave - Top", False, []],
|
["Superbunny Cave - Top", False, []],
|
||||||
["Superbunny Cave - Top", False, [], ['Progressive Glove', 'Flute']],
|
["Superbunny Cave - Top", True, ['Flute']],
|
||||||
["Superbunny Cave - Top", True, ['Progressive Glove', 'Lamp']],
|
["Superbunny Cave - Top", True, ['Progressive Glove', 'Lamp']],
|
||||||
["Superbunny Cave - Top", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
|
||||||
["Superbunny Cave - Top", True, ['Hammer', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
|
||||||
|
|
||||||
["Superbunny Cave - Bottom", False, []],
|
["Superbunny Cave - Bottom", False, []],
|
||||||
["Superbunny Cave - Bottom", False, [], ['Progressive Glove', 'Flute']],
|
["Superbunny Cave - Bottom", True, ['Flute']],
|
||||||
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Lamp']],
|
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Lamp']],
|
||||||
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
|
||||||
["Superbunny Cave - Bottom", True, ['Hammer', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Bottom Right", False, []],
|
["Hookshot Cave - Bottom Right", False, []],
|
||||||
["Hookshot Cave - Bottom Right", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Bottom Right", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Bottom Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Bottom Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Pegasus Boots']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Pegasus Boots']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Pegasus Boots']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Flute', 'Pegasus Boots']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Pegasus Boots']],
|
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Bottom Left", False, []],
|
["Hookshot Cave - Bottom Left", False, []],
|
||||||
["Hookshot Cave - Bottom Left", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Bottom Left", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Bottom Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Bottom Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Top Left", False, []],
|
["Hookshot Cave - Top Left", False, []],
|
||||||
["Hookshot Cave - Top Left", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Top Left", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Top Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Top Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Top Right", False, []],
|
["Hookshot Cave - Top Right", False, []],
|
||||||
["Hookshot Cave - Top Right", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Top Right", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Top Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Top Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def testWestDarkWorldDeathMountain(self):
|
def testWestDarkWorldDeathMountain(self):
|
||||||
|
@ -211,20 +197,20 @@ class TestInvertedDeathMountain(TestInverted):
|
||||||
["Spike Cave", False, [], ['Cape', 'Cane of Byrna']],
|
["Spike Cave", False, [], ['Cape', 'Cane of Byrna']],
|
||||||
["Spike Cave", False, [], ['Cane of Byrna', 'AnyBottle', 'Magic Upgrade (1/2)']],
|
["Spike Cave", False, [], ['Cane of Byrna', 'AnyBottle', 'Magic Upgrade (1/2)']],
|
||||||
["Spike Cave", False, [], ['AnyBottle', 'Magic Upgrade (1/2)', 'Pegasus Boots', 'Boss Heart Container', 'Piece of Heart', 'Sanctuary Heart Container']],
|
["Spike Cave", False, [], ['AnyBottle', 'Magic Upgrade (1/2)', 'Pegasus Boots', 'Boss Heart Container', 'Piece of Heart', 'Sanctuary Heart Container']],
|
||||||
|
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||||
# Change from base ER - this fork places a blue potion in dark world
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Cape']],
|
||||||
#["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Cape']],
|
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cape']],
|
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
#["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cape']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Cape']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
|
|
||||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -6,29 +6,32 @@ class TestEntrances(TestInverted):
|
||||||
def testDungeonEntrances(self):
|
def testDungeonEntrances(self):
|
||||||
self.run_entrance_tests([
|
self.run_entrance_tests([
|
||||||
["Hyrule Castle Entrance (South)", False, []],
|
["Hyrule Castle Entrance (South)", False, []],
|
||||||
["Hyrule Castle Entrance (South)", False, [], ["Beat Agahnim 1", "Moon Pearl"]],
|
["Hyrule Castle Entrance (South)", False, [], ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
||||||
["Hyrule Castle Entrance (South)", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", False, [], ["Flute", "Beat Agahnim 1", "Progressive Glove"]],
|
||||||
["Hyrule Castle Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
||||||
["Hyrule Castle Entrance (South)", True, ["Beat Agahnim 1"]],
|
["Hyrule Castle Entrance (South)", True, ["Beat Agahnim 1"]],
|
||||||
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
||||||
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
["Hyrule Castle Entrance (South)", True, ["Flute", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
|
||||||
["Eastern Palace", False, []],
|
["Eastern Palace", False, []],
|
||||||
["Eastern Palace", False, [], ["Beat Agahnim 1", "Moon Pearl"]],
|
["Eastern Palace", False, [], ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
||||||
["Eastern Palace", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
["Eastern Palace", False, [], ["Flute", "Beat Agahnim 1", "Progressive Glove"]],
|
||||||
["Eastern Palace", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
["Eastern Palace", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
||||||
["Eastern Palace", True, ["Beat Agahnim 1"]],
|
["Eastern Palace", True, ["Beat Agahnim 1"]],
|
||||||
["Eastern Palace", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
["Eastern Palace", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
||||||
["Eastern Palace", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
["Eastern Palace", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
["Eastern Palace", True, ["Flute", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
|
||||||
["Desert Palace Entrance (South)", False, []],
|
["Desert Palace Entrance (South)", False, []],
|
||||||
["Desert Palace Entrance (South)", False, [], ["Book of Mudora"]],
|
["Desert Palace Entrance (South)", False, [], ["Book of Mudora"]],
|
||||||
["Desert Palace Entrance (South)", False, [], ["Beat Agahnim 1", "Moon Pearl"]],
|
["Desert Palace Entrance (South)", False, [], ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
||||||
["Desert Palace Entrance (South)", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Beat Agahnim 1"]],
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Beat Agahnim 1"]],
|
||||||
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Hammer", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Hammer", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Flute", "Progressive Glove", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (North)", False, []],
|
["Desert Palace Entrance (North)", False, []],
|
||||||
["Desert Palace Entrance (North)", False, [], ["Book of Mudora"]],
|
["Desert Palace Entrance (North)", False, [], ["Book of Mudora"]],
|
||||||
["Desert Palace Entrance (North)", False, [], ["Progressive Glove"]],
|
["Desert Palace Entrance (North)", False, [], ["Progressive Glove"]],
|
||||||
|
@ -46,26 +49,21 @@ class TestEntrances(TestInverted):
|
||||||
["Tower of Hera", False, [], ["Flute", "Progressive Glove"]],
|
["Tower of Hera", False, [], ["Flute", "Progressive Glove"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Progressive Glove", "Progressive Glove", "Lamp"]],
|
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Progressive Glove", "Progressive Glove", "Lamp"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Progressive Glove", "Lamp"]],
|
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Progressive Glove", "Lamp"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Progressive Glove", "Flute"]],
|
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Flute"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Beat Agahnim 1", "Flute", "Hookshot"]],
|
|
||||||
|
|
||||||
["Inverted Agahnims Tower", False, []],
|
["Inverted Agahnims Tower", False, []],
|
||||||
["Inverted Agahnims Tower", False, [], ["Flute", "Lamp"]],
|
["Inverted Agahnims Tower", False, [], ["Flute", "Lamp"]],
|
||||||
["Inverted Agahnims Tower", False, [], ["Flute", "Progressive Glove"]],
|
["Inverted Agahnims Tower", False, [], ["Flute", "Progressive Glove"]],
|
||||||
["Inverted Agahnims Tower", False, [], ["Moon Pearl", "Lamp"]],
|
|
||||||
["Inverted Agahnims Tower", False, [], ["Moon Pearl", "Progressive Glove"]],
|
|
||||||
["Inverted Agahnims Tower", True, ["Lamp", "Progressive Glove"]],
|
["Inverted Agahnims Tower", True, ["Lamp", "Progressive Glove"]],
|
||||||
["Inverted Agahnims Tower", True, ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
["Inverted Agahnims Tower", True, ["Flute"]],
|
||||||
["Inverted Agahnims Tower", True, ["Flute", "Progressive Glove", "Progressive Glove", "Moon Pearl"]],
|
|
||||||
["Inverted Agahnims Tower", True, ["Flute", "Progressive Glove", "Hammer", "Moon Pearl"]],
|
|
||||||
|
|
||||||
["Palace of Darkness", False, []],
|
["Palace of Darkness", False, []],
|
||||||
["Palace of Darkness", False, [], ["Hammer", "Flippers", "Magic Mirror", "Flute"]],
|
["Palace of Darkness", False, [], ["Hammer", "Flippers", "Magic Mirror", "Flute"]],
|
||||||
["Palace of Darkness", True, ["Hammer"]],
|
["Palace of Darkness", True, ["Hammer"]],
|
||||||
["Palace of Darkness", True, ["Flippers"]],
|
["Palace of Darkness", True, ["Flippers"]],
|
||||||
["Palace of Darkness", True, ["Progressive Glove", "Progressive Glove", "Moon Pearl", "Flute"]],
|
["Palace of Darkness", True, ["Flute"]],
|
||||||
["Palace of Darkness", True, ["Progressive Glove", "Progressive Glove", "Moon Pearl", "Magic Mirror"]],
|
["Palace of Darkness", True, ["Progressive Glove", "Progressive Glove", "Moon Pearl", "Magic Mirror"]],
|
||||||
["Palace of Darkness", True, ["Beat Agahnim 1", "Moon Pearl", "Flute"]],
|
["Palace of Darkness", True, ["Flute"]],
|
||||||
# Moon Pearl not needed, you can mirror as Bunny
|
# Moon Pearl not needed, you can mirror as Bunny
|
||||||
["Palace of Darkness", True, ["Beat Agahnim 1", "Magic Mirror"]],
|
["Palace of Darkness", True, ["Beat Agahnim 1", "Magic Mirror"]],
|
||||||
|
|
||||||
|
@ -85,15 +83,12 @@ class TestEntrances(TestInverted):
|
||||||
|
|
||||||
["Misery Mire", False, []],
|
["Misery Mire", False, []],
|
||||||
["Misery Mire", False, [], ["Flute", "Magic Mirror"]],
|
["Misery Mire", False, [], ["Flute", "Magic Mirror"]],
|
||||||
["Misery Mire", False, [], ["Moon Pearl", "Magic Mirror"]],
|
|
||||||
["Misery Mire", False, [], ["Ether"]],
|
["Misery Mire", False, [], ["Ether"]],
|
||||||
["Misery Mire", False, [], ["Progressive Sword"]],
|
["Misery Mire", False, [], ["Progressive Sword"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Beat Agahnim 1", "Magic Mirror"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Beat Agahnim 1", "Magic Mirror"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Beat Agahnim 1", "Moon Pearl", "Flute"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Flute"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Hammer", "Progressive Glove", "Magic Mirror"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Hammer", "Progressive Glove", "Magic Mirror"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Hammer", "Progressive Glove", "Flute"]],
|
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Progressive Glove", "Progressive Glove", "Magic Mirror"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Progressive Glove", "Progressive Glove", "Magic Mirror"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Progressive Glove", "Progressive Glove", "Flute"]],
|
|
||||||
|
|
||||||
["Turtle Rock", False, []],
|
["Turtle Rock", False, []],
|
||||||
["Turtle Rock", False, [], ["Quake"]],
|
["Turtle Rock", False, [], ["Quake"]],
|
||||||
|
@ -101,9 +96,7 @@ class TestEntrances(TestInverted):
|
||||||
["Turtle Rock", False, [], ["Lamp", "Flute"]],
|
["Turtle Rock", False, [], ["Lamp", "Flute"]],
|
||||||
["Turtle Rock", False, [], ["Progressive Glove", "Flute"]],
|
["Turtle Rock", False, [], ["Progressive Glove", "Flute"]],
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Lamp"]],
|
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Lamp"]],
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Progressive Glove", "Moon Pearl", "Flute"]],
|
["Turtle Rock", True, ["Quake", "Progressive Sword", "Flute"]],
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Hammer", "Moon Pearl", "Flute"]],
|
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Beat Agahnim 1", "Moon Pearl", "Flute"]],
|
|
||||||
|
|
||||||
["Inverted Ganons Tower", False, []],
|
["Inverted Ganons Tower", False, []],
|
||||||
["Inverted Ganons Tower", False, [], ["Crystal 1"]],
|
["Inverted Ganons Tower", False, [], ["Crystal 1"]],
|
||||||
|
|
|
@ -191,7 +191,8 @@ class TestInvertedLightWorld(TestInverted):
|
||||||
["Bombos Tablet", False, []],
|
["Bombos Tablet", False, []],
|
||||||
["Bombos Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
["Bombos Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||||
["Bombos Tablet", False, [], ['Book of Mudora']],
|
["Bombos Tablet", False, [], ['Book of Mudora']],
|
||||||
["Bombos Tablet", False, [], ['Moon Pearl', 'Beat Agahnim 1']],
|
# Flute to Mire, take portal
|
||||||
|
["Bombos Tablet", True, ['Flute', 'Book of Mudora', 'Progressive Glove', 'Progressive Glove', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Bombos Tablet", True, ['Beat Agahnim 1', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Bombos Tablet", True, ['Beat Agahnim 1', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Progressive Glove', 'Progressive Sword', 'Progressive Sword']],
|
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Progressive Glove', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Hammer', 'Progressive Sword', 'Progressive Sword']],
|
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Hammer', 'Progressive Sword', 'Progressive Sword']],
|
||||||
|
|
|
@ -9,70 +9,70 @@ class TestInvertedTurtleRock(TestInverted):
|
||||||
["Turtle Rock - Compass Chest", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Compass Chest", False, [], ['Cane of Somaria']],
|
||||||
["Turtle Rock - Compass Chest", False, [], ['Quake', 'Magic Mirror']],
|
["Turtle Rock - Compass Chest", False, [], ['Quake', 'Magic Mirror']],
|
||||||
["Turtle Rock - Compass Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Compass Chest", True, ['Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Compass Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Chain Chomps", False, []],
|
["Turtle Rock - Chain Chomps", False, []],
|
||||||
["Turtle Rock - Chain Chomps", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Chain Chomps", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
# Item rando only needs 1 key. ER needs to consider the case when the back is accessible, but not the middle (key wasted on Trinexx door)
|
# Item rando only needs 1 key. ER needs to consider the case when the back is accessible, but not the middle (key wasted on Trinexx door)
|
||||||
["Turtle Rock - Chain Chomps", False, ['Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Chain Chomps", False, ['Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Chain Chomps", True, ['Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
["Turtle Rock - Chain Chomps", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
||||||
|
|
||||||
["Turtle Rock - Roller Room - Left", False, []],
|
["Turtle Rock - Roller Room - Left", False, []],
|
||||||
["Turtle Rock - Roller Room - Left", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Roller Room - Left", False, [], ['Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Left", False, [], ['Fire Rod']],
|
["Turtle Rock - Roller Room - Left", False, [], ['Fire Rod']],
|
||||||
["Turtle Rock - Roller Room - Left", False, [], ['Quake', 'Magic Mirror']],
|
["Turtle Rock - Roller Room - Left", False, [], ['Quake', 'Magic Mirror']],
|
||||||
["Turtle Rock - Roller Room - Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Moon Pearl', 'Fire Rod', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Roller Room - Right", False, []],
|
["Turtle Rock - Roller Room - Right", False, []],
|
||||||
["Turtle Rock - Roller Room - Right", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Roller Room - Right", False, [], ['Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Right", False, [], ['Fire Rod']],
|
["Turtle Rock - Roller Room - Right", False, [], ['Fire Rod']],
|
||||||
["Turtle Rock - Roller Room - Right", False, [], ['Quake', 'Magic Mirror']],
|
["Turtle Rock - Roller Room - Right", False, [], ['Quake', 'Magic Mirror']],
|
||||||
["Turtle Rock - Roller Room - Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Moon Pearl', 'Fire Rod', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Big Chest", False, []],
|
["Turtle Rock - Big Chest", False, []],
|
||||||
["Turtle Rock - Big Chest", False, [], ['Big Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", False, [], ['Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Big Chest", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Big Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hookshot']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Hookshot']],
|
||||||
|
|
||||||
["Turtle Rock - Big Key Chest", False, []],
|
["Turtle Rock - Big Key Chest", False, []],
|
||||||
["Turtle Rock - Big Key Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
# Mirror in from ledge, use left side entrance, have enough keys to get to the chest
|
# Mirror in from ledge, use left side entrance, have enough keys to get to the chest
|
||||||
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Crystaroller Room", False, []],
|
["Turtle Rock - Crystaroller Room", False, []],
|
||||||
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
||||||
|
@ -80,117 +80,15 @@ class TestInvertedTurtleRock(TestInverted):
|
||||||
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Lamp']],
|
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Lamp']],
|
||||||
["Turtle Rock - Crystaroller Room", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Crystaroller Room", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Crystaroller Room", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']],
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
# Mirroring into Eye Bridge does not require Cane of Somaria
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Boss", False, []],
|
["Turtle Rock - Boss", False, []],
|
||||||
["Turtle Rock - Boss", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Boss", False, [], ['Cane of Somaria']],
|
||||||
|
@ -200,9 +98,42 @@ class TestInvertedTurtleRock(TestInverted):
|
||||||
["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']],
|
["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']],
|
||||||
["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Flute', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']]
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Flute', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def testEyeBridge(self):
|
||||||
|
for location in ["Turtle Rock - Eye Bridge - Top Right", "Turtle Rock - Eye Bridge - Top Left",
|
||||||
|
"Turtle Rock - Eye Bridge - Bottom Right", "Turtle Rock - Eye Bridge - Bottom Left"]:
|
||||||
|
self.run_location_tests([
|
||||||
|
[location, False, []],
|
||||||
|
[location, False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
||||||
|
[location, False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
||||||
|
[location, False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
|
[location, False, [], ['Magic Mirror', 'Lamp']],
|
||||||
|
[location, False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
|
||||||
|
# Mirroring into Eye Bridge does not require Cane of Somaria
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
||||||
|
[location, True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cape']],
|
||||||
|
[location, True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
|
@ -88,15 +88,9 @@ class TestInvertedDarkWorld(TestInvertedMinor):
|
||||||
self.run_location_tests([
|
self.run_location_tests([
|
||||||
["Mire Shed - Left", False, []],
|
["Mire Shed - Left", False, []],
|
||||||
["Mire Shed - Left", False, [], ['Flute', 'Magic Mirror']],
|
["Mire Shed - Left", False, [], ['Flute', 'Magic Mirror']],
|
||||||
["Mire Shed - Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove']],
|
["Mire Shed - Left", True, ['Flute']],
|
||||||
["Mire Shed - Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Mire Shed - Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1']],
|
|
||||||
["Mire Shed - Left", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
|
||||||
|
|
||||||
["Mire Shed - Right", False, []],
|
["Mire Shed - Right", False, []],
|
||||||
["Mire Shed - Right", False, [], ['Flute', 'Magic Mirror']],
|
["Mire Shed - Right", False, [], ['Flute', 'Magic Mirror']],
|
||||||
["Mire Shed - Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove']],
|
["Mire Shed - Right", True, ['Flute']],
|
||||||
["Mire Shed - Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Mire Shed - Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1']],
|
|
||||||
["Mire Shed - Right", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
|
||||||
])
|
])
|
|
@ -9,16 +9,13 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Old Man", False, [], ['Progressive Glove', 'Flute']],
|
["Old Man", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Old Man", False, [], ['Lamp']],
|
["Old Man", False, [], ['Lamp']],
|
||||||
["Old Man", True, ['Progressive Glove', 'Lamp']],
|
["Old Man", True, ['Progressive Glove', 'Lamp']],
|
||||||
["Old Man", False, ['Flute', 'Lamp']],
|
["Old Man", True, ['Flute', 'Lamp']],
|
||||||
|
|
||||||
["Spectacle Rock Cave", False, []],
|
["Spectacle Rock Cave", False, []],
|
||||||
["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Flute']],
|
["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Spectacle Rock Cave", False, [], ['Lamp', 'Flute']],
|
["Spectacle Rock Cave", False, [], ['Lamp', 'Flute']],
|
||||||
["Spectacle Rock Cave", False, ['Flute', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Spectacle Rock Cave", False, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Spectacle Rock Cave", False, ['Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Spectacle Rock Cave", False, ['Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Spectacle Rock Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
["Spectacle Rock Cave", True, ['Flute']],
|
||||||
["Spectacle Rock Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
|
||||||
["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']],
|
["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -31,8 +28,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Spiral Cave", False, ['Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Spiral Cave", False, ['Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Spiral Cave", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Spiral Cave", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Spiral Cave", False, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
["Spiral Cave", False, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||||
["Spiral Cave", False, ['Flute', 'Hookshot', 'Moon Pearl']],
|
["Spiral Cave", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Spiral Cave", True, ['Flute', 'Hookshot', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
|
||||||
["Spiral Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hookshot']],
|
["Spiral Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hookshot']],
|
||||||
["Spiral Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Spiral Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Spiral Cave", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Spiral Cave", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -44,7 +40,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Lower - Far Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Far Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Far Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -56,7 +52,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Lower - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -68,7 +64,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Lower - Middle", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Middle", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Middle", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Middle", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Middle", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -80,7 +76,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Lower - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -92,7 +88,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Lower - Far Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Lower - Far Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Lower - Far Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Lower - Far Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Lower - Far Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -104,7 +100,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Upper - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Upper - Left", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Upper - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Upper - Left", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -116,7 +112,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Paradox Cave Upper - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Paradox Cave Upper - Right", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Paradox Cave Upper - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", False, ['Flute', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Flute', 'Progressive Glove', 'Hammer', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Flute', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Lamp', 'Hookshot', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||||
["Paradox Cave Upper - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
["Paradox Cave Upper - Right", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||||
|
@ -126,7 +122,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Mimic Cave", False, [], ['Hammer']],
|
["Mimic Cave", False, [], ['Hammer']],
|
||||||
["Mimic Cave", False, [], ['Progressive Glove', 'Flute']],
|
["Mimic Cave", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Mimic Cave", False, [], ['Lamp', 'Flute']],
|
["Mimic Cave", False, [], ['Lamp', 'Flute']],
|
||||||
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot']],
|
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
["Mimic Cave", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||||
["Mimic Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
["Mimic Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Mimic Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
["Mimic Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
||||||
|
@ -139,7 +135,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Ether Tablet", False, [], ['Hammer']],
|
["Ether Tablet", False, [], ['Hammer']],
|
||||||
["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||||
["Ether Tablet", False, [], ['Book of Mudora']],
|
["Ether Tablet", False, [], ['Book of Mudora']],
|
||||||
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Ether Tablet", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Ether Tablet", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
|
@ -150,7 +146,7 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Spectacle Rock", False, [], ['Lamp', 'Flute']],
|
["Spectacle Rock", False, [], ['Lamp', 'Flute']],
|
||||||
["Spectacle Rock", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
["Spectacle Rock", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||||
["Spectacle Rock", False, [], ['Hammer']],
|
["Spectacle Rock", False, [], ['Hammer']],
|
||||||
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot']],
|
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
["Spectacle Rock", True, ['Flute', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||||
["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||||
["Spectacle Rock", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
["Spectacle Rock", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
||||||
|
@ -161,45 +157,38 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Superbunny Cave - Top", False, []],
|
["Superbunny Cave - Top", False, []],
|
||||||
["Superbunny Cave - Top", False, [], ['Progressive Glove', 'Flute']],
|
["Superbunny Cave - Top", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Superbunny Cave - Top", True, ['Progressive Glove', 'Lamp']],
|
["Superbunny Cave - Top", True, ['Progressive Glove', 'Lamp']],
|
||||||
["Superbunny Cave - Top", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
["Superbunny Cave - Top", True, ['Flute']],
|
||||||
["Superbunny Cave - Top", True, ['Hammer', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
|
||||||
|
|
||||||
["Superbunny Cave - Bottom", False, []],
|
["Superbunny Cave - Bottom", False, []],
|
||||||
["Superbunny Cave - Bottom", False, [], ['Progressive Glove', 'Flute']],
|
["Superbunny Cave - Bottom", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Lamp']],
|
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Lamp']],
|
||||||
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
["Superbunny Cave - Bottom", True, ['Flute']],
|
||||||
["Superbunny Cave - Bottom", True, ['Hammer', 'Progressive Glove', 'Moon Pearl', 'Flute']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Bottom Right", False, []],
|
["Hookshot Cave - Bottom Right", False, []],
|
||||||
["Hookshot Cave - Bottom Right", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Bottom Right", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Bottom Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Bottom Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Pegasus Boots']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Pegasus Boots']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Pegasus Boots']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Flute', 'Pegasus Boots']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Pegasus Boots']],
|
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Bottom Left", False, []],
|
["Hookshot Cave - Bottom Left", False, []],
|
||||||
["Hookshot Cave - Bottom Left", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Bottom Left", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Bottom Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Bottom Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Top Left", False, []],
|
["Hookshot Cave - Top Left", False, []],
|
||||||
["Hookshot Cave - Top Left", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Top Left", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Top Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Top Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
|
|
||||||
["Hookshot Cave - Top Right", False, []],
|
["Hookshot Cave - Top Right", False, []],
|
||||||
["Hookshot Cave - Top Right", False, [], ['Progressive Glove', 'Flute']],
|
["Hookshot Cave - Top Right", False, [], ['Progressive Glove', 'Flute']],
|
||||||
["Hookshot Cave - Top Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
["Hookshot Cave - Top Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Flute', 'Hookshot']],
|
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Flute', 'Hookshot']],
|
||||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Flute', 'Hookshot']],
|
|
||||||
])
|
])
|
||||||
|
|
||||||
def testWestDarkWorldDeathMountain(self):
|
def testWestDarkWorldDeathMountain(self):
|
||||||
|
@ -211,19 +200,18 @@ class TestInvertedDeathMountain(TestInvertedMinor):
|
||||||
["Spike Cave", False, [], ['Cane of Byrna', 'AnyBottle', 'Magic Upgrade (1/2)']],
|
["Spike Cave", False, [], ['Cane of Byrna', 'AnyBottle', 'Magic Upgrade (1/2)']],
|
||||||
["Spike Cave", False, [], ['AnyBottle', 'Magic Upgrade (1/2)', 'Pegasus Boots', 'Boss Heart Container', 'Piece of Heart', 'Sanctuary Heart Container']],
|
["Spike Cave", False, [], ['AnyBottle', 'Magic Upgrade (1/2)', 'Pegasus Boots', 'Boss Heart Container', 'Piece of Heart', 'Sanctuary Heart Container']],
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||||
# Change from base ER - this fork places a blue potion in dark world
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Cape']],
|
||||||
#["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Cape']],
|
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cape']],
|
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
#["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cape']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Cape']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
|
|
||||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -6,29 +6,32 @@ class TestEntrances(TestInvertedMinor):
|
||||||
def testDungeonEntrances(self):
|
def testDungeonEntrances(self):
|
||||||
self.run_entrance_tests([
|
self.run_entrance_tests([
|
||||||
["Hyrule Castle Entrance (South)", False, []],
|
["Hyrule Castle Entrance (South)", False, []],
|
||||||
["Hyrule Castle Entrance (South)", False, [], ["Beat Agahnim 1", "Moon Pearl"]],
|
["Hyrule Castle Entrance (South)", False, [], ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
||||||
["Hyrule Castle Entrance (South)", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", False, [], ["Flute", "Beat Agahnim 1", "Progressive Glove"]],
|
||||||
["Hyrule Castle Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
||||||
["Hyrule Castle Entrance (South)", True, ["Beat Agahnim 1"]],
|
["Hyrule Castle Entrance (South)", True, ["Beat Agahnim 1"]],
|
||||||
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
||||||
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
["Hyrule Castle Entrance (South)", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
["Hyrule Castle Entrance (South)", True, ["Flute", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
|
||||||
["Eastern Palace", False, []],
|
["Eastern Palace", False, []],
|
||||||
["Eastern Palace", False, [], ["Beat Agahnim 1", "Moon Pearl"]],
|
["Eastern Palace", False, [], ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
||||||
["Eastern Palace", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
["Eastern Palace", False, [], ["Flute", "Beat Agahnim 1", "Progressive Glove"]],
|
||||||
["Eastern Palace", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
["Eastern Palace", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
||||||
["Eastern Palace", True, ["Beat Agahnim 1"]],
|
["Eastern Palace", True, ["Beat Agahnim 1"]],
|
||||||
["Eastern Palace", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
["Eastern Palace", True, ["Moon Pearl", "Hammer", "Progressive Glove"]],
|
||||||
["Eastern Palace", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
["Eastern Palace", True, ["Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
["Eastern Palace", True, ["Flute", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
|
||||||
["Desert Palace Entrance (South)", False, []],
|
["Desert Palace Entrance (South)", False, []],
|
||||||
["Desert Palace Entrance (South)", False, [], ["Book of Mudora"]],
|
["Desert Palace Entrance (South)", False, [], ["Book of Mudora"]],
|
||||||
["Desert Palace Entrance (South)", False, [], ["Beat Agahnim 1", "Moon Pearl"]],
|
["Desert Palace Entrance (South)", False, [], ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
||||||
["Desert Palace Entrance (South)", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", False, [], ["Beat Agahnim 1", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", False, ["Progressive Glove"], ["Beat Agahnim 1", "Hammer", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Beat Agahnim 1"]],
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Beat Agahnim 1"]],
|
||||||
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Hammer", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Hammer", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Moon Pearl", "Progressive Glove", "Progressive Glove"]],
|
||||||
|
["Desert Palace Entrance (South)", True, ["Book of Mudora", "Flute", "Progressive Glove", "Progressive Glove"]],
|
||||||
["Desert Palace Entrance (North)", False, []],
|
["Desert Palace Entrance (North)", False, []],
|
||||||
["Desert Palace Entrance (North)", False, [], ["Book of Mudora"]],
|
["Desert Palace Entrance (North)", False, [], ["Book of Mudora"]],
|
||||||
["Desert Palace Entrance (North)", False, [], ["Progressive Glove"]],
|
["Desert Palace Entrance (North)", False, [], ["Progressive Glove"]],
|
||||||
|
@ -46,18 +49,13 @@ class TestEntrances(TestInvertedMinor):
|
||||||
["Tower of Hera", False, [], ["Flute", "Progressive Glove"]],
|
["Tower of Hera", False, [], ["Flute", "Progressive Glove"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Progressive Glove", "Progressive Glove", "Lamp"]],
|
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Progressive Glove", "Progressive Glove", "Lamp"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Progressive Glove", "Lamp"]],
|
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Progressive Glove", "Lamp"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Progressive Glove", "Flute"]],
|
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Hookshot", "Flute"]],
|
||||||
["Tower of Hera", True, ["Moon Pearl", "Hammer", "Beat Agahnim 1", "Flute", "Hookshot"]],
|
|
||||||
|
|
||||||
["Inverted Agahnims Tower", False, []],
|
["Inverted Agahnims Tower", False, []],
|
||||||
["Inverted Agahnims Tower", False, [], ["Flute", "Lamp"]],
|
["Inverted Agahnims Tower", False, [], ["Flute", "Lamp"]],
|
||||||
["Inverted Agahnims Tower", False, [], ["Flute", "Progressive Glove"]],
|
["Inverted Agahnims Tower", False, [], ["Flute", "Progressive Glove"]],
|
||||||
["Inverted Agahnims Tower", False, [], ["Moon Pearl", "Lamp"]],
|
|
||||||
["Inverted Agahnims Tower", False, [], ["Moon Pearl", "Progressive Glove"]],
|
|
||||||
["Inverted Agahnims Tower", True, ["Lamp", "Progressive Glove"]],
|
["Inverted Agahnims Tower", True, ["Lamp", "Progressive Glove"]],
|
||||||
["Inverted Agahnims Tower", True, ["Flute", "Beat Agahnim 1", "Moon Pearl"]],
|
["Inverted Agahnims Tower", True, ["Flute"]],
|
||||||
["Inverted Agahnims Tower", True, ["Flute", "Progressive Glove", "Progressive Glove", "Moon Pearl"]],
|
|
||||||
["Inverted Agahnims Tower", True, ["Flute", "Progressive Glove", "Hammer", "Moon Pearl"]],
|
|
||||||
|
|
||||||
["Palace of Darkness", True, []],
|
["Palace of Darkness", True, []],
|
||||||
|
|
||||||
|
@ -75,15 +73,12 @@ class TestEntrances(TestInvertedMinor):
|
||||||
|
|
||||||
["Misery Mire", False, []],
|
["Misery Mire", False, []],
|
||||||
["Misery Mire", False, [], ["Flute", "Magic Mirror"]],
|
["Misery Mire", False, [], ["Flute", "Magic Mirror"]],
|
||||||
["Misery Mire", False, [], ["Moon Pearl", "Magic Mirror"]],
|
|
||||||
["Misery Mire", False, [], ["Ether"]],
|
["Misery Mire", False, [], ["Ether"]],
|
||||||
["Misery Mire", False, [], ["Progressive Sword"]],
|
["Misery Mire", False, [], ["Progressive Sword"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Beat Agahnim 1", "Magic Mirror"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Beat Agahnim 1", "Magic Mirror"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Beat Agahnim 1", "Moon Pearl", "Flute"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Flute"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Hammer", "Progressive Glove", "Magic Mirror"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Hammer", "Progressive Glove", "Magic Mirror"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Hammer", "Progressive Glove", "Flute"]],
|
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Progressive Glove", "Progressive Glove", "Magic Mirror"]],
|
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Progressive Glove", "Progressive Glove", "Magic Mirror"]],
|
||||||
["Misery Mire", True, ["Progressive Sword", "Ether", "Moon Pearl", "Progressive Glove", "Progressive Glove", "Flute"]],
|
|
||||||
|
|
||||||
["Turtle Rock", False, []],
|
["Turtle Rock", False, []],
|
||||||
["Turtle Rock", False, [], ["Quake"]],
|
["Turtle Rock", False, [], ["Quake"]],
|
||||||
|
@ -91,9 +86,7 @@ class TestEntrances(TestInvertedMinor):
|
||||||
["Turtle Rock", False, [], ["Lamp", "Flute"]],
|
["Turtle Rock", False, [], ["Lamp", "Flute"]],
|
||||||
["Turtle Rock", False, [], ["Progressive Glove", "Flute"]],
|
["Turtle Rock", False, [], ["Progressive Glove", "Flute"]],
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Lamp"]],
|
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Lamp"]],
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Progressive Glove", "Moon Pearl", "Flute"]],
|
["Turtle Rock", True, ["Quake", "Progressive Sword", "Flute"]],
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Progressive Glove", "Hammer", "Moon Pearl", "Flute"]],
|
|
||||||
["Turtle Rock", True, ["Quake", "Progressive Sword", "Beat Agahnim 1", "Moon Pearl", "Flute"]],
|
|
||||||
|
|
||||||
["Inverted Ganons Tower", False, []],
|
["Inverted Ganons Tower", False, []],
|
||||||
["Inverted Ganons Tower", False, [], ["Crystal 1"]],
|
["Inverted Ganons Tower", False, [], ["Crystal 1"]],
|
||||||
|
|
|
@ -186,7 +186,8 @@ class TestInvertedLightWorld(TestInvertedMinor):
|
||||||
["Bombos Tablet", False, []],
|
["Bombos Tablet", False, []],
|
||||||
["Bombos Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
["Bombos Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||||
["Bombos Tablet", False, [], ['Book of Mudora']],
|
["Bombos Tablet", False, [], ['Book of Mudora']],
|
||||||
["Bombos Tablet", False, [], ['Moon Pearl', 'Beat Agahnim 1']],
|
# Flute to Mire, take portal
|
||||||
|
["Bombos Tablet", True, ['Flute', 'Book of Mudora', 'Progressive Glove', 'Progressive Glove', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Bombos Tablet", True, ['Beat Agahnim 1', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
["Bombos Tablet", True, ['Beat Agahnim 1', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Progressive Glove', 'Progressive Sword', 'Progressive Sword']],
|
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Progressive Glove', 'Progressive Sword', 'Progressive Sword']],
|
||||||
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Hammer', 'Progressive Sword', 'Progressive Sword']],
|
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Progressive Glove', 'Hammer', 'Progressive Sword', 'Progressive Sword']],
|
||||||
|
|
|
@ -9,70 +9,70 @@ class TestInvertedTurtleRock(TestInvertedMinor):
|
||||||
["Turtle Rock - Compass Chest", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Compass Chest", False, [], ['Cane of Somaria']],
|
||||||
["Turtle Rock - Compass Chest", False, [], ['Quake', 'Magic Mirror']],
|
["Turtle Rock - Compass Chest", False, [], ['Quake', 'Magic Mirror']],
|
||||||
["Turtle Rock - Compass Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Compass Chest", True, ['Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Compass Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Compass Chest", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Compass Chest", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Chain Chomps", False, []],
|
["Turtle Rock - Chain Chomps", False, []],
|
||||||
["Turtle Rock - Chain Chomps", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Chain Chomps", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
# Item rando only needs 1 key. ER needs to consider the case when the back is accessible, but not the middle (key wasted on Trinexx door)
|
# Item rando only needs 1 key. ER needs to consider the case when the back is accessible, but not the middle (key wasted on Trinexx door)
|
||||||
["Turtle Rock - Chain Chomps", False, ['Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Chain Chomps", False, ['Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Chain Chomps", True, ['Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
["Turtle Rock - Chain Chomps", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']],
|
||||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
["Turtle Rock - Chain Chomps", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
||||||
|
|
||||||
["Turtle Rock - Roller Room - Left", False, []],
|
["Turtle Rock - Roller Room - Left", False, []],
|
||||||
["Turtle Rock - Roller Room - Left", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Roller Room - Left", False, [], ['Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Left", False, [], ['Fire Rod']],
|
["Turtle Rock - Roller Room - Left", False, [], ['Fire Rod']],
|
||||||
["Turtle Rock - Roller Room - Left", False, [], ['Quake', 'Magic Mirror']],
|
["Turtle Rock - Roller Room - Left", False, [], ['Quake', 'Magic Mirror']],
|
||||||
["Turtle Rock - Roller Room - Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Moon Pearl', 'Fire Rod', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Left", True, ['Fire Rod', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Roller Room - Right", False, []],
|
["Turtle Rock - Roller Room - Right", False, []],
|
||||||
["Turtle Rock - Roller Room - Right", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Roller Room - Right", False, [], ['Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Right", False, [], ['Fire Rod']],
|
["Turtle Rock - Roller Room - Right", False, [], ['Fire Rod']],
|
||||||
["Turtle Rock - Roller Room - Right", False, [], ['Quake', 'Magic Mirror']],
|
["Turtle Rock - Roller Room - Right", False, [], ['Quake', 'Magic Mirror']],
|
||||||
["Turtle Rock - Roller Room - Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Quake', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Moon Pearl', 'Fire Rod', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Roller Room - Right", True, ['Fire Rod', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Big Chest", False, []],
|
["Turtle Rock - Big Chest", False, []],
|
||||||
["Turtle Rock - Big Chest", False, [], ['Big Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", False, [], ['Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Big Chest", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Big Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hookshot']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Hookshot']],
|
||||||
|
|
||||||
["Turtle Rock - Big Key Chest", False, []],
|
["Turtle Rock - Big Key Chest", False, []],
|
||||||
["Turtle Rock - Big Key Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
# Mirror in from ledge, use left side entrance, have enough keys to get to the chest
|
# Mirror in from ledge, use left side entrance, have enough keys to get to the chest
|
||||||
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Big Key Chest", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Big Key Chest", True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
|
|
||||||
["Turtle Rock - Crystaroller Room", False, []],
|
["Turtle Rock - Crystaroller Room", False, []],
|
||||||
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
||||||
|
@ -80,117 +80,15 @@ class TestInvertedTurtleRock(TestInvertedMinor):
|
||||||
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Lamp']],
|
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Lamp']],
|
||||||
["Turtle Rock - Crystaroller Room", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Crystaroller Room", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Crystaroller Room", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']],
|
||||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']],
|
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']],
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
# Mirroring into Eye Bridge does not require Cane of Somaria
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, []],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, [], ['Magic Mirror', 'Lamp']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
|
||||||
|
|
||||||
["Turtle Rock - Boss", False, []],
|
["Turtle Rock - Boss", False, []],
|
||||||
["Turtle Rock - Boss", False, [], ['Cane of Somaria']],
|
["Turtle Rock - Boss", False, [], ['Cane of Somaria']],
|
||||||
|
@ -200,9 +98,43 @@ class TestInvertedTurtleRock(TestInvertedMinor):
|
||||||
["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']],
|
["Turtle Rock - Boss", False, [], ['Magic Mirror', 'Lamp']],
|
||||||
["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
["Turtle Rock - Boss", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Small Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Moon Pearl', 'Flute', 'Beat Agahnim 1', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Flute', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Bottle', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Progressive Sword', 'Cane of Somaria', 'Magic Upgrade (1/2)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)','Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']],
|
||||||
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Flute', 'Beat Agahnim 1', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']]
|
["Turtle Rock - Boss", True, ['Ice Rod', 'Fire Rod', 'Flute', 'Magic Mirror', 'Moon Pearl', 'Hookshot', 'Hammer', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Big Key (Turtle Rock)']]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def testEyeBridge(self):
|
||||||
|
for location in ["Turtle Rock - Eye Bridge - Top Right", "Turtle Rock - Eye Bridge - Top Left",
|
||||||
|
"Turtle Rock - Eye Bridge - Bottom Right", "Turtle Rock - Eye Bridge - Bottom Left"]:
|
||||||
|
self.run_location_tests([
|
||||||
|
[location, False, []],
|
||||||
|
[location, False, ['Progressive Shield', 'Progressive Shield'], ['Progressive Shield', 'Cape', 'Cane of Byrna']],
|
||||||
|
[location, False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
||||||
|
[location, False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||||
|
[location, False, [], ['Magic Mirror', 'Lamp']],
|
||||||
|
[location, False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Cape']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Cape']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Flute', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Lamp', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Big Key (Turtle Rock)', 'Lamp', 'Progressive Glove', 'Quake', 'Progressive Sword', 'Cane of Somaria', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
|
||||||
|
# Mirroring into Eye Bridge does not require Cane of Somaria
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Byrna']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cape']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cape']],
|
||||||
|
[location, True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Cape']],
|
||||||
|
[location, True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cape']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Moon Pearl', 'Flute', 'Magic Mirror', 'Hookshot', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
[location, True, ['Flute', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
|
@ -78,14 +78,14 @@ class TestDeathMountain(TestInvertedOWG):
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||||
# Change from base ER - this fork places a blue potion in dark world
|
# Change from base ER - this fork places a blue potion in dark world
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cape']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Cape']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Magic Upgrade (1/2)', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Cane of Byrna']],
|
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||||
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Flute', 'Moon Pearl', 'Cane of Byrna']],
|
["Spike Cave", True, ['Boss Heart Container', 'Hammer', 'Progressive Glove', 'Flute', 'Cane of Byrna']],
|
||||||
])
|
])
|
||||||
|
|
||||||
def testEastDarkWorldDeathMountain(self):
|
def testEastDarkWorldDeathMountain(self):
|
||||||
|
|
Loading…
Reference in New Issue