Merge remote-tracking branch 'upstream/DoorDevUnstable' into OverworldShuffle
This commit is contained in:
137
.github/workflows/ci.yml
vendored
137
.github/workflows/ci.yml
vendored
@@ -27,15 +27,15 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os-name: [ ubuntu-latest, ubuntu-18.04, macOS-latest, windows-latest ]
|
||||
python-version: [ 3.8 ]
|
||||
python-version: [ 3.9 ]
|
||||
# needs: [ install-test ]
|
||||
steps:
|
||||
# checkout commit
|
||||
- name: Checkout commit
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v2
|
||||
# install python
|
||||
- name: Install python
|
||||
uses: actions/setup-python@v1
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: "x64"
|
||||
@@ -48,6 +48,28 @@ jobs:
|
||||
run: |
|
||||
python ./resources/ci/common/install.py
|
||||
pip install pyinstaller
|
||||
# get parent directory
|
||||
- name: Get Repo Name
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: repoName
|
||||
with:
|
||||
source: ${{ github.repository }}
|
||||
find: '${{ github.repository_owner }}/'
|
||||
replace: ''
|
||||
- name: Get Parent Directory Path (!Windows)
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: parentDirNotWin
|
||||
with:
|
||||
source: ${{ github.workspace }}
|
||||
find: '${{ steps.repoName.outputs.value }}/${{ steps.repoName.outputs.value }}'
|
||||
replace: ${{ steps.repoName.outputs.value }}
|
||||
- name: Get Parent Directory Path (Windows)
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: parentDir
|
||||
with:
|
||||
source: ${{ steps.parentDirNotWin.outputs.value }}
|
||||
find: '${{ steps.repoName.outputs.value }}\${{ steps.repoName.outputs.value }}'
|
||||
replace: ${{ steps.repoName.outputs.value }}
|
||||
# try to get UPX
|
||||
- name: Get UPX
|
||||
env:
|
||||
@@ -70,10 +92,10 @@ jobs:
|
||||
python ./resources/ci/common/prepare_binary.py
|
||||
# upload binary artifacts for later step
|
||||
- name: Upload Binary Artifacts
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: binaries-${{ matrix.os-name }}
|
||||
path: ../artifact
|
||||
path: ${{ steps.parentDir.outputs.value }}/artifact
|
||||
|
||||
# Install & Preparing Release
|
||||
# Set up environment
|
||||
@@ -87,18 +109,18 @@ jobs:
|
||||
# os & python versions
|
||||
strategy:
|
||||
matrix:
|
||||
# install/release on not xenial
|
||||
# install/release on not bionic
|
||||
os-name: [ ubuntu-latest, ubuntu-18.04, macOS-latest, windows-latest ]
|
||||
python-version: [ 3.8 ]
|
||||
python-version: [ 3.9 ]
|
||||
|
||||
needs: [ install-build ]
|
||||
steps:
|
||||
# checkout commit
|
||||
- name: Checkout commit
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v2
|
||||
# install python
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v1
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: "x64"
|
||||
@@ -110,9 +132,31 @@ jobs:
|
||||
OS_NAME: ${{ matrix.os-name }}
|
||||
run: |
|
||||
python ./resources/ci/common/install.py
|
||||
# get parent directory
|
||||
- name: Get Repo Name
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: repoName
|
||||
with:
|
||||
source: ${{ github.repository }}
|
||||
find: '${{ github.repository_owner }}/'
|
||||
replace: ''
|
||||
- name: Get Parent Directory Path (!Windows)
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: parentDirNotWin
|
||||
with:
|
||||
source: ${{ github.workspace }}
|
||||
find: '${{ steps.repoName.outputs.value }}/${{ steps.repoName.outputs.value }}'
|
||||
replace: ${{ steps.repoName.outputs.value }}
|
||||
- name: Get Parent Directory Path (Windows)
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: parentDir
|
||||
with:
|
||||
source: ${{ steps.parentDirNotWin.outputs.value }}
|
||||
find: '${{ steps.repoName.outputs.value }}\${{ steps.repoName.outputs.value }}'
|
||||
replace: ${{ steps.repoName.outputs.value }}
|
||||
# download binary artifact
|
||||
- name: Download Binary Artifact
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: binaries-${{ matrix.os-name }}
|
||||
path: ./
|
||||
@@ -126,22 +170,22 @@ jobs:
|
||||
python ./resources/ci/common/prepare_release.py
|
||||
# upload appversion artifact for later step
|
||||
- name: Upload AppVersion Artifact
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: appversion-${{ matrix.os-name }}
|
||||
path: ./resources/app/meta/manifests/app_version.txt
|
||||
# upload archive artifact for later step
|
||||
- name: Upload Archive Artifact
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: archive-${{ matrix.os-name }}
|
||||
path: ../deploy
|
||||
path: ${{ steps.parentDir.outputs.value }}/deploy
|
||||
|
||||
# Deploy to GitHub Releases
|
||||
# Release Name: ALttPDoorRandomizer v${GITHUB_TAG}
|
||||
# Release Body: Inline content of RELEASENOTES.md
|
||||
# Release Body: Fallback to URL to RELEASENOTES.md
|
||||
# Release Files: ../deploy
|
||||
# Release Files: ${{ steps.parentDir.outputs.value }}/deploy
|
||||
deploy-release:
|
||||
name: Deploy GHReleases
|
||||
runs-on: ${{ matrix.os-name }}
|
||||
@@ -150,42 +194,64 @@ jobs:
|
||||
# os & python versions
|
||||
strategy:
|
||||
matrix:
|
||||
# release only on focal/bionic
|
||||
# release only on focal
|
||||
os-name: [ ubuntu-latest ]
|
||||
python-version: [ 3.8 ]
|
||||
python-version: [ 3.9 ]
|
||||
|
||||
needs: [ install-prepare-release ]
|
||||
steps:
|
||||
# checkout commit
|
||||
- name: Checkout commit
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v2
|
||||
# get parent directory
|
||||
- name: Get Repo Name
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: repoName
|
||||
with:
|
||||
source: ${{ github.repository }}
|
||||
find: '${{ github.repository_owner }}/'
|
||||
replace: ''
|
||||
- name: Get Parent Directory Path (!Windows)
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: parentDirNotWin
|
||||
with:
|
||||
source: ${{ github.workspace }}
|
||||
find: '${{ steps.repoName.outputs.value }}/${{ steps.repoName.outputs.value }}'
|
||||
replace: ${{ steps.repoName.outputs.value }}
|
||||
- name: Get Parent Directory Path (Windows)
|
||||
uses: mad9000/actions-find-and-replace-string@1
|
||||
id: parentDir
|
||||
with:
|
||||
source: ${{ steps.parentDirNotWin.outputs.value }}
|
||||
find: '${{ steps.repoName.outputs.value }}\${{ steps.repoName.outputs.value }}'
|
||||
replace: ${{ steps.repoName.outputs.value }}
|
||||
- name: Install Dependencies via pip
|
||||
run: |
|
||||
python -m pip install pytz requests
|
||||
# download appversion artifact
|
||||
- name: Download AppVersion Artifact
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: appversion-${{ matrix.os-name }}
|
||||
path: ../build
|
||||
path: ${{ steps.parentDir.outputs.value }}/build
|
||||
# download ubuntu archive artifact
|
||||
- name: Download Ubuntu Archive Artifact
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: archive-ubuntu-latest
|
||||
path: ../deploy/linux
|
||||
path: ${{ steps.parentDir.outputs.value }}/deploy/linux
|
||||
# download macos archive artifact
|
||||
- name: Download MacOS Archive Artifact
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: archive-macOS-latest
|
||||
path: ../deploy/macos
|
||||
path: ${{ steps.parentDir.outputs.value }}/deploy/macos
|
||||
# download windows archive artifact
|
||||
- name: Download Windows Archive Artifact
|
||||
uses: actions/download-artifact@v1
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: archive-windows-latest
|
||||
path: ../deploy/windows
|
||||
path: ${{ steps.parentDir.outputs.value }}/deploy/windows
|
||||
# debug info
|
||||
- name: Debug Info
|
||||
id: debug_info
|
||||
@@ -199,44 +265,35 @@ jobs:
|
||||
RELEASE_NAME="ALttPDoorRandomizer ${GITHUB_TAG}"
|
||||
echo "Release Name: ${RELEASE_NAME}"
|
||||
echo "Git Tag: ${GITHUB_TAG}"
|
||||
# read releasenotes
|
||||
- name: Read RELEASENOTES
|
||||
id: release_notes
|
||||
run: |
|
||||
body="$(cat RELEASENOTES.md)"
|
||||
body="${body//'%'/'%25'}"
|
||||
body="${body//$'\n'/'%0A'}"
|
||||
body="${body//$'\r'/'%0D'}"
|
||||
echo "::set-output name=body::$body"
|
||||
# create a pre/release
|
||||
- name: Create a Pre/Release
|
||||
id: create_release
|
||||
uses: actions/create-release@master
|
||||
uses: actions/create-release@v1.1.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: v${{ steps.debug_info.outputs.github_tag }}
|
||||
release_name: ALttPDoorRandomizer v${{ steps.debug_info.outputs.github_tag }}
|
||||
body: ${{ steps.release_notes.outputs.body }}
|
||||
body_path: RELEASENOTES.md
|
||||
draft: true
|
||||
prerelease: true
|
||||
if: contains(github.ref, 'master') || contains(github.ref, 'stable') || contains(github.ref, 'dev') || contains(github.ref, 'DoorRelease')
|
||||
# upload linux archive asset
|
||||
- name: Upload Linux Archive Asset
|
||||
id: upload-linux-asset
|
||||
uses: actions/upload-release-asset@v1.0.1
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ../deploy/linux/ALttPDoorRandomizer.tar.gz
|
||||
asset_name: ALttPDoorRandomizer-${{ steps.debug_info.outputs.github_tag }}-linux-bionic.tar.gz
|
||||
asset_name: ALttPDoorRandomizer-${{ steps.debug_info.outputs.github_tag }}-linux-focal.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
if: contains(github.ref, 'master') || contains(github.ref, 'stable') || contains(github.ref, 'dev') || contains(github.ref, 'DoorRelease')
|
||||
# upload macos archive asset
|
||||
- name: Upload MacOS Archive Asset
|
||||
id: upload-macos-asset
|
||||
uses: actions/upload-release-asset@v1.0.1
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
@@ -248,7 +305,7 @@ jobs:
|
||||
# upload windows archive asset
|
||||
- name: Upload Windows Archive Asset
|
||||
id: upload-windows-asset
|
||||
uses: actions/upload-release-asset@v1.0.1
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -24,6 +24,9 @@ weights/
|
||||
/MultiMystery/
|
||||
/Players/
|
||||
/QUsb2Snes/
|
||||
/output/
|
||||
|
||||
base2current.json
|
||||
|
||||
resources/user/*
|
||||
!resources/user/.gitkeep
|
||||
@@ -35,3 +38,4 @@ get-pip.py
|
||||
venv
|
||||
test
|
||||
*.code-workspace
|
||||
*.zspr
|
||||
|
||||
@@ -131,6 +131,7 @@ class World(object):
|
||||
set_player_attr('open_pyramid', False)
|
||||
set_player_attr('treasure_hunt_icon', 'Triforce Piece')
|
||||
set_player_attr('treasure_hunt_count', 0)
|
||||
set_player_attr('treasure_hunt_total', 0)
|
||||
set_player_attr('potshuffle', False)
|
||||
set_player_attr('pot_contents', None)
|
||||
|
||||
@@ -623,7 +624,8 @@ class CollectionState(object):
|
||||
for event in reachable_events:
|
||||
if event.name in flooded_keys.keys():
|
||||
flood_location = self.world.get_location(flooded_keys[event.name], event.player)
|
||||
if flood_location.item and flood_location not in self.locations_checked:
|
||||
if (flood_location.item and flood_location not in self.locations_checked
|
||||
and self.location_can_be_flooded(flood_location)):
|
||||
adjusted_checks.remove(event)
|
||||
if len(adjusted_checks) < len(reachable_events):
|
||||
return adjusted_checks
|
||||
@@ -634,9 +636,14 @@ class CollectionState(object):
|
||||
flood_location = world.get_location(flooded_keys[location.name], location.player)
|
||||
item = flood_location.item
|
||||
item_is_important = False if not item else item.advancement or item.bigkey or item.smallkey
|
||||
return flood_location in self.locations_checked or not item_is_important
|
||||
return (flood_location in self.locations_checked or not item_is_important
|
||||
or not self.location_can_be_flooded(flood_location))
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def location_can_be_flooded(location):
|
||||
return location.parent_region.name in ['Swamp Trench 1 Alcove', 'Swamp Trench 2 Alcove']
|
||||
|
||||
def has(self, item, player, count=1):
|
||||
if count == 1:
|
||||
return (item, player) in self.prog_items
|
||||
@@ -814,14 +821,17 @@ class CollectionState(object):
|
||||
elif 'Shield' in item.name:
|
||||
if self.has('Mirror Shield', item.player):
|
||||
pass
|
||||
elif self.has('Red Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 3:
|
||||
elif self.has('Shield Level', item.player, 2) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 3:
|
||||
self.prog_items['Mirror Shield', item.player] += 1
|
||||
self.prog_items['Shield Level', item.player] += 1
|
||||
changed = True
|
||||
elif self.has('Blue Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 2:
|
||||
elif self.has('Shield Level', item.player, 1) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 2:
|
||||
self.prog_items['Red Shield', item.player] += 1
|
||||
self.prog_items['Shield Level', item.player] += 1
|
||||
changed = True
|
||||
elif self.world.difficulty_requirements[item.player].progressive_shield_limit >= 1:
|
||||
self.prog_items['Blue Shield', item.player] += 1
|
||||
self.prog_items['Shield Level', item.player] += 1
|
||||
changed = True
|
||||
elif 'Bow' in item.name:
|
||||
if self.has('Silver Arrows', item.player):
|
||||
@@ -1414,6 +1424,11 @@ class Door(object):
|
||||
else:
|
||||
self.passage = False
|
||||
|
||||
def kind(self, world):
|
||||
if self.roomIndex != -1 and self.doorListPos != -1:
|
||||
return world.get_room(self.roomIndex, self.player).kind(self)
|
||||
return None
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__) and self.name == other.name
|
||||
|
||||
@@ -2064,6 +2079,8 @@ class Spoiler(object):
|
||||
'experimental': self.world.experimental,
|
||||
'keydropshuffle': self.world.keydropshuffle,
|
||||
'shopsanity': self.world.shopsanity,
|
||||
'triforcegoal': self.world.treasure_hunt_count,
|
||||
'triforcepool': self.world.treasure_hunt_total,
|
||||
'code': {p: Settings.make_code(self.world, p) for p in range(1, self.world.players + 1)}
|
||||
}
|
||||
|
||||
@@ -2108,6 +2125,9 @@ class Spoiler(object):
|
||||
outfile.write('Retro: %s\n' % ('Yes' if self.metadata['retro'][player] else 'No'))
|
||||
outfile.write('Swords: %s\n' % self.metadata['weapons'][player])
|
||||
outfile.write('Goal: %s\n' % self.metadata['goal'][player])
|
||||
if self.metadata['goal'][player] == 'triforcehunt':
|
||||
outfile.write('Triforce Pieces Required: %s\n' % self.metadata['triforcegoal'][player])
|
||||
outfile.write('Triforce Pieces Total: %s\n' % self.metadata['triforcepool'][player])
|
||||
outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player])
|
||||
outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player])
|
||||
outfile.write('Overworld Shuffle: %s\n' % self.metadata['ow_shuffle'][player])
|
||||
@@ -2295,8 +2315,8 @@ counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3}
|
||||
access_mode = {"items": 0, "locations": 1, "none": 2}
|
||||
|
||||
# byte 6: BSMC BBEE (big, small, maps, compass, bosses, enemies)
|
||||
boss_mode = {"none": 0, "simple": 1, "full": 2, "random": 3}
|
||||
enemy_mode = {"none": 0, "shuffled": 1, "random": 2}
|
||||
boss_mode = {"none": 0, "simple": 1, "full": 2, "random": 3, "chaos": 3}
|
||||
enemy_mode = {"none": 0, "shuffled": 1, "random": 2, "chaos": 2}
|
||||
|
||||
# byte 7: HHHD DP?? (enemy_health, enemy_dmg, potshuffle, ?)
|
||||
e_health = {"default": 0, "easy": 1, "normal": 2, "hard": 3, "expert": 4}
|
||||
|
||||
@@ -39,6 +39,7 @@ def MoldormDefeatRule(state, player):
|
||||
return state.has_blunt_weapon(player)
|
||||
|
||||
def HelmasaurKingDefeatRule(state, player):
|
||||
# TODO: technically possible with the hammer
|
||||
return state.has_sword(player) or state.can_shoot_arrows(player)
|
||||
|
||||
def ArrghusDefeatRule(state, player):
|
||||
|
||||
111
CLI.py
111
CLI.py
@@ -6,7 +6,6 @@ import textwrap
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
import source.classes.constants as CONST
|
||||
from source.classes.BabelFish import BabelFish
|
||||
|
||||
from Utils import update_deprecated_args
|
||||
@@ -17,6 +16,7 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
|
||||
def _get_help_string(self, action):
|
||||
return textwrap.dedent(action.help)
|
||||
|
||||
|
||||
def parse_cli(argv, no_defaults=False):
|
||||
def defval(value):
|
||||
return value if not no_defaults else None
|
||||
@@ -28,50 +28,57 @@ def parse_cli(argv, no_defaults=False):
|
||||
fish = BabelFish(lang=lang)
|
||||
|
||||
# we need to know how many players we have first
|
||||
# also if we're loading our own settings file, we should do that now
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument('--settingsfile', help="input json file of settings", type=str)
|
||||
parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255))
|
||||
multiargs, _ = parser.parse_known_args(argv)
|
||||
|
||||
if multiargs.settingsfile:
|
||||
settings = apply_settings_file(settings, multiargs.settingsfile)
|
||||
|
||||
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
|
||||
|
||||
# get args
|
||||
args = []
|
||||
with open(os.path.join("resources","app","cli","args.json")) as argsFile:
|
||||
args = json.load(argsFile)
|
||||
for arg in args:
|
||||
argdata = args[arg]
|
||||
argname = "--" + arg
|
||||
argatts = {}
|
||||
argatts["help"] = "(default: %(default)s)"
|
||||
if "action" in argdata:
|
||||
argatts["action"] = argdata["action"]
|
||||
if "choices" in argdata:
|
||||
argatts["choices"] = argdata["choices"]
|
||||
argatts["const"] = argdata["choices"][0]
|
||||
argatts["default"] = argdata["choices"][0]
|
||||
argatts["nargs"] = "?"
|
||||
if arg in settings:
|
||||
default = settings[arg]
|
||||
if "type" in argdata and argdata["type"] == "bool":
|
||||
default = settings[arg] != 0
|
||||
argatts["default"] = defval(default)
|
||||
arghelp = fish.translate("cli","help",arg)
|
||||
if "help" in argdata and argdata["help"] == "suppress":
|
||||
argatts["help"] = argparse.SUPPRESS
|
||||
elif not isinstance(arghelp,str):
|
||||
argatts["help"] = '\n'.join(arghelp).replace("\\'","'")
|
||||
else:
|
||||
argatts["help"] = arghelp + " " + argatts["help"]
|
||||
parser.add_argument(argname,**argatts)
|
||||
with open(os.path.join("resources", "app", "cli", "args.json")) as argsFile:
|
||||
args = json.load(argsFile)
|
||||
for arg in args:
|
||||
argdata = args[arg]
|
||||
argname = "--" + arg
|
||||
argatts = {}
|
||||
argatts["help"] = "(default: %(default)s)"
|
||||
if "action" in argdata:
|
||||
argatts["action"] = argdata["action"]
|
||||
if "choices" in argdata:
|
||||
argatts["choices"] = argdata["choices"]
|
||||
argatts["const"] = argdata["choices"][0]
|
||||
argatts["default"] = argdata["choices"][0]
|
||||
argatts["nargs"] = "?"
|
||||
if arg in settings:
|
||||
default = settings[arg]
|
||||
if "type" in argdata and argdata["type"] == "bool":
|
||||
default = settings[arg] != 0
|
||||
argatts["default"] = defval(default)
|
||||
arghelp = fish.translate("cli", "help", arg)
|
||||
if "help" in argdata and argdata["help"] == "suppress":
|
||||
argatts["help"] = argparse.SUPPRESS
|
||||
elif not isinstance(arghelp, str):
|
||||
argatts["help"] = '\n'.join(arghelp).replace("\\'", "'")
|
||||
else:
|
||||
argatts["help"] = arghelp + " " + argatts["help"]
|
||||
parser.add_argument(argname, **argatts)
|
||||
|
||||
parser.add_argument('--seed', default=defval(int(settings["seed"]) if settings["seed"] != "" and settings["seed"] is not None else None), help="\n".join(fish.translate("cli","help","seed")), type=int)
|
||||
parser.add_argument('--count', default=defval(int(settings["count"]) if settings["count"] != "" and settings["count"] is not None else 1), help="\n".join(fish.translate("cli","help","count")), type=int)
|
||||
parser.add_argument('--seed', default=defval(int(settings["seed"]) if settings["seed"] != "" and settings["seed"] is not None else None), help="\n".join(fish.translate("cli", "help", "seed")), type=int)
|
||||
parser.add_argument('--count', default=defval(int(settings["count"]) if settings["count"] != "" and settings["count"] is not None else 1), help="\n".join(fish.translate("cli", "help", "count")), type=int)
|
||||
parser.add_argument('--customitemarray', default={}, help=argparse.SUPPRESS)
|
||||
|
||||
# included for backwards compatibility
|
||||
parser.add_argument('--beemizer', default=defval(settings["beemizer"]), type=lambda value: min(max(int(value), 0), 4))
|
||||
parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255))
|
||||
parser.add_argument('--securerandom', default=defval(settings["securerandom"]), action='store_true')
|
||||
parser.add_argument('--teams', default=defval(1), type=lambda value: max(int(value), 1))
|
||||
parser.add_argument('--settingsfile', dest="filename", help="input json file of settings", type=str)
|
||||
|
||||
if multiargs.multi:
|
||||
for player in range(1, multiargs.multi + 1):
|
||||
@@ -85,11 +92,13 @@ def parse_cli(argv, no_defaults=False):
|
||||
if multiargs.multi:
|
||||
defaults = copy.deepcopy(ret)
|
||||
for player in range(1, multiargs.multi + 1):
|
||||
playerargs = parse_cli(shlex.split(getattr(ret,f"p{player}")), True)
|
||||
playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True)
|
||||
|
||||
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'ow_shuffle',
|
||||
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
||||
'triforce_min_difference', 'triforce_goal', 'triforce_pool',
|
||||
'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters',
|
||||
'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots',
|
||||
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep',
|
||||
@@ -103,6 +112,15 @@ def parse_cli(argv, no_defaults=False):
|
||||
return ret
|
||||
|
||||
|
||||
def apply_settings_file(settings, settings_path):
|
||||
if os.path.exists(settings_path):
|
||||
with open(settings_path) as json_file:
|
||||
data = json.load(json_file)
|
||||
for k, v in data.items():
|
||||
settings[k] = v
|
||||
return settings
|
||||
|
||||
|
||||
def parse_settings():
|
||||
# set default settings
|
||||
settings = {
|
||||
@@ -147,10 +165,19 @@ def parse_settings():
|
||||
"dungeon_counters": "default",
|
||||
"mixed_travel": "prevent",
|
||||
"standardize_palettes": "standardize",
|
||||
|
||||
"triforce_pool": 30,
|
||||
"triforce_goal": 20,
|
||||
"triforce_pool_min": 0,
|
||||
"triforce_pool_max": 0,
|
||||
"triforce_goal_min": 0,
|
||||
"triforce_goal_max": 0,
|
||||
"triforce_min_difference": 10,
|
||||
|
||||
"code": "",
|
||||
"multi": 1,
|
||||
"names": "",
|
||||
"securerandom": False,
|
||||
|
||||
# Hints default to TRUE
|
||||
"hints": True,
|
||||
@@ -159,15 +186,15 @@ def parse_settings():
|
||||
"quickswap": False,
|
||||
"heartcolor": "red",
|
||||
"heartbeep": "normal",
|
||||
"sprite": os.path.join(".","data","sprites","official","001.link.1.zspr"),
|
||||
"sprite": os.path.join(".", "data", "sprites", "official", "001.link.1.zspr"),
|
||||
"fastmenu": "normal",
|
||||
"ow_palettes": "default",
|
||||
"uw_palettes": "default",
|
||||
|
||||
# Spoiler defaults to FALSE
|
||||
# Spoiler defaults to TRUE
|
||||
# Playthrough defaults to TRUE
|
||||
# ROM defaults to TRUE
|
||||
"create_spoiler": False,
|
||||
"create_spoiler": True,
|
||||
"calc_playthrough": True,
|
||||
"create_rom": True,
|
||||
"usestartinventory": False,
|
||||
@@ -265,17 +292,15 @@ def parse_settings():
|
||||
|
||||
# read saved settings file if it exists and set these
|
||||
settings_path = os.path.join(".", "resources", "user", "settings.json")
|
||||
if os.path.exists(settings_path):
|
||||
with(open(settings_path)) as json_file:
|
||||
data = json.load(json_file)
|
||||
for k, v in data.items():
|
||||
settings[k] = v
|
||||
settings = apply_settings_file(settings, settings_path)
|
||||
return settings
|
||||
|
||||
# Priority fallback is:
|
||||
# 1: CLI
|
||||
# 2: Settings file
|
||||
# 2: Settings file(s)
|
||||
# 3: Canned defaults
|
||||
|
||||
|
||||
def get_args_priority(settings_args, gui_args, cli_args):
|
||||
args = {}
|
||||
args["settings"] = parse_settings() if settings_args is None else settings_args
|
||||
@@ -302,7 +327,7 @@ def get_args_priority(settings_args, gui_args, cli_args):
|
||||
for k in vars(args["cli"]):
|
||||
load_doesnt_have_key = k not in args["load"]
|
||||
cli_val = cli[k]
|
||||
if isinstance(cli_val,dict) and 1 in cli_val:
|
||||
if isinstance(cli_val, dict) and 1 in cli_val:
|
||||
cli_val = cli_val[1]
|
||||
different_val = (k in args["load"] and k in cli) and (str(args["load"][k]) != str(cli_val))
|
||||
cli_has_empty_dict = k in cli and isinstance(cli_val, dict) and len(cli_val) == 0
|
||||
@@ -311,9 +336,9 @@ def get_args_priority(settings_args, gui_args, cli_args):
|
||||
args["load"][k] = cli_val
|
||||
|
||||
newArgs = {}
|
||||
for key in [ "settings", "gui", "cli", "load" ]:
|
||||
for key in ["settings", "gui", "cli", "load"]:
|
||||
if args[key]:
|
||||
if isinstance(args[key],dict):
|
||||
if isinstance(args[key], dict):
|
||||
newArgs[key] = argparse.Namespace(**args[key])
|
||||
else:
|
||||
newArgs[key] = args[key]
|
||||
|
||||
@@ -42,6 +42,7 @@ def link_doors(world, player):
|
||||
disconnect_portal(portal, world, player)
|
||||
reset_portals(world, player)
|
||||
reset_rooms(world, player)
|
||||
world.get_door("Skull Pinball WS", player).no_exit()
|
||||
|
||||
|
||||
def link_doors_main(world, player):
|
||||
@@ -67,7 +68,7 @@ def link_doors_main(world, player):
|
||||
for entrance, ext in ladders:
|
||||
connect_two_way(world, entrance, ext, player)
|
||||
|
||||
if world.intensity[player] < 3 or world.doorShuffle == 'vanilla':
|
||||
if world.intensity[player] < 3 or world.doorShuffle[player] == 'vanilla':
|
||||
mirror_route = world.get_entrance('Sanctuary Mirror Route', player)
|
||||
mr_door = mirror_route.door
|
||||
sanctuary = mirror_route.parent_region
|
||||
@@ -397,7 +398,10 @@ def choose_portals(world, player):
|
||||
|
||||
master_door_list = [x for x in world.doors if x.player == player and x.portalAble]
|
||||
portal_assignment = defaultdict(list)
|
||||
for dungeon, info in info_map.items():
|
||||
shuffled_info = list(info_map.items())
|
||||
if cross_flag:
|
||||
random.shuffle(shuffled_info)
|
||||
for dungeon, info in shuffled_info:
|
||||
outstanding_portals = list(dungeon_portals[dungeon])
|
||||
hc_flag = std_flag and dungeon == 'Hyrule Castle'
|
||||
if hc_flag:
|
||||
@@ -543,7 +547,7 @@ def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allo
|
||||
bk_shuffle=False, standard=False):
|
||||
ret = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req]
|
||||
if crossed:
|
||||
ret = [x for x in ret if not x.dungeonLink or x.entrance.parent_region.dungeon.name == dungeon]
|
||||
ret = [x for x in ret if not x.dungeonLink or x.dungeonLink == dungeon or x.dungeonLink.startswith('link')]
|
||||
else:
|
||||
ret = [x for x in ret if x.entrance.parent_region.dungeon.name == dungeon]
|
||||
if need_passage:
|
||||
|
||||
20
Doors.py
20
Doors.py
@@ -206,7 +206,7 @@ def create_doors(world, player):
|
||||
create_door(player, 'Desert East Wing Key Door EN', Intr).dir(Ea, 0x85, Top, High).small_key().pos(1),
|
||||
create_door(player, 'Desert Compass Key Door WN', Intr).dir(We, 0x85, Top, High).small_key().pos(1),
|
||||
create_door(player, 'Desert Compass NW', Nrml).dir(No, 0x85, Right, High).trap(0x4).pos(0),
|
||||
create_door(player, 'Desert Cannonball S', Nrml).dir(So, 0x75, Right, High).pos(1).portal(Z, 0x02),
|
||||
create_door(player, 'Desert Cannonball S', Nrml).dir(So, 0x75, Right, High).pos(1).portal(X, 0x02),
|
||||
create_door(player, 'Desert Arrow Pot Corner S Edge', Open).dir(So, 0x75, None, High).edge(6, Z, 0x20),
|
||||
create_door(player, 'Desert Arrow Pot Corner W Edge', Open).dir(We, 0x75, None, High).edge(2, Z, 0x20),
|
||||
create_door(player, 'Desert Arrow Pot Corner NW', Intr).dir(No, 0x75, Left, High).pos(0),
|
||||
@@ -1312,12 +1312,7 @@ def create_doors(world, player):
|
||||
# can't unlink from skull woods right now
|
||||
world.get_door('Skull 2 West Lobby S', player).dungeonLink = 'Skull Woods'
|
||||
|
||||
world.get_door('Ice Spike Cross SE', player).dungeonLink = 'linkIceFalls'
|
||||
world.get_door('Ice Tall Hint SE', player).dungeonLink = 'linkIceFalls'
|
||||
world.get_door('Ice Switch Room SE', player).dungeonLink = 'linkIceFalls'
|
||||
|
||||
world.get_door('Ice Cross Bottom SE', player).dungeonLink = 'linkIceFalls2'
|
||||
world.get_door('Ice Conveyor SW', player).dungeonLink = 'linkIceFalls2'
|
||||
set_special_dungeon_links(world, player)
|
||||
|
||||
|
||||
def create_portals(world, player):
|
||||
@@ -1351,10 +1346,21 @@ def create_portals(world, player):
|
||||
world.dungeon_portals[player] += dungeon_portals
|
||||
|
||||
|
||||
def set_special_dungeon_links(world, player):
|
||||
world.get_door('Ice Spike Cross SE', player).dungeonLink = 'linkIceFalls'
|
||||
world.get_door('Ice Tall Hint SE', player).dungeonLink = 'linkIceFalls'
|
||||
world.get_door('Ice Switch Room SE', player).dungeonLink = 'linkIceFalls'
|
||||
|
||||
world.get_door('Ice Cross Bottom SE', player).dungeonLink = 'linkIceFalls2'
|
||||
world.get_door('Ice Conveyor SW', player).dungeonLink = 'linkIceFalls2'
|
||||
|
||||
|
||||
def reset_portals(world, player):
|
||||
world.dungeon_portals[player].clear()
|
||||
world._portal_cache.clear()
|
||||
create_portals(world, player)
|
||||
set_special_dungeon_links(world, player)
|
||||
|
||||
|
||||
def create_paired_doors(world, player):
|
||||
world.paired_doors[player] = [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import random
|
||||
|
||||
# ToDo: With shuffle_ganon option, prevent gtower from linking to an exit only location through a 2 entrance cave.
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def link_entrances(world, player):
|
||||
@@ -1117,11 +1118,9 @@ def link_inverted_entrances(world, player):
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)')
|
||||
dp_must_exit = 'Desert Palace Entrance (North)'
|
||||
lw_entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (West)')
|
||||
dp_must_exit = 'Desert Palace Entrance (West)'
|
||||
lw_entrances.append('Desert Palace Entrance (North)')
|
||||
|
||||
dungeon_exits.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'))
|
||||
@@ -1157,13 +1156,10 @@ def link_inverted_entrances(world, player):
|
||||
|
||||
connect_two_way(world, aga_door, 'Inverted Agahnims Tower Exit', player)
|
||||
dungeon_exits.remove('Inverted Agahnims Tower Exit')
|
||||
|
||||
all_dungeon_entrances = dw_entrances + lw_entrances
|
||||
connect_mandatory_exits(world, all_dungeon_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player, dp_must_exit)
|
||||
|
||||
remaining_dw_entrances = [i for i in all_dungeon_entrances if i in dw_entrances]
|
||||
remaining_lw_entrances = [i for i in all_dungeon_entrances if i in lw_entrances]
|
||||
connect_caves(world, remaining_lw_entrances, remaining_dw_entrances, dungeon_exits, player)
|
||||
|
||||
connect_mandatory_exits(world, lw_entrances, dungeon_exits, lw_dungeon_entrances_must_exit, player)
|
||||
|
||||
connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player)
|
||||
|
||||
elif world.shuffle[player] == 'simple':
|
||||
simple_shuffle_dungeons(world, player)
|
||||
@@ -1271,7 +1267,7 @@ def link_inverted_entrances(world, player):
|
||||
caves = list(Cave_Exits + Cave_Three_Exits + Old_Man_House)
|
||||
single_doors = list(Single_Cave_Doors)
|
||||
bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors)
|
||||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
|
||||
blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors)
|
||||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
|
||||
# place links house
|
||||
@@ -1354,18 +1350,16 @@ def link_inverted_entrances(world, player):
|
||||
old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Inverted Agahnims Tower', 'Tower of Hera'])
|
||||
caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues
|
||||
bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors)
|
||||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
|
||||
blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors)
|
||||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
old_man_house = list(Old_Man_House)
|
||||
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
lw_must_exits.append('Desert Palace Entrance (North)')
|
||||
dp_must_exit = 'Desert Palace Entrance (North)'
|
||||
lw_entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
lw_must_exits.append('Desert Palace Entrance (West)')
|
||||
dp_must_exit = 'Desert Palace Entrance (West)'
|
||||
lw_entrances.append('Desert Palace Entrance (North)')
|
||||
|
||||
# tavern back door cannot be shuffled yet
|
||||
@@ -1428,7 +1422,7 @@ def link_inverted_entrances(world, player):
|
||||
# no dw must exits in inverted, but we randomize whether cave is in light or dark world
|
||||
if random.randint(0, 1) == 0:
|
||||
caves += old_man_house
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player, dp_must_exit)
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player)
|
||||
try:
|
||||
caves.remove(old_man_house[0])
|
||||
except ValueError:
|
||||
@@ -1437,7 +1431,7 @@ def link_inverted_entrances(world, player):
|
||||
connect_caves(world, lw_entrances, [], old_man_house, player)
|
||||
else:
|
||||
connect_caves(world, dw_entrances, [], old_man_house, player)
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player, dp_must_exit)
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player)
|
||||
|
||||
# place old man, has limited options
|
||||
# exit has to come from specific set of doors, the entrance is free to move about
|
||||
@@ -1506,17 +1500,15 @@ def link_inverted_entrances(world, player):
|
||||
old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Inverted Agahnims Tower', 'Tower of Hera'])
|
||||
caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits + Old_Man_House) # don't need to consider three exit caves, have one exit caves to avoid parity issues
|
||||
bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors)
|
||||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
|
||||
blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors)
|
||||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
must_exits.append('Desert Palace Entrance (North)')
|
||||
dp_must_exit = 'Desert Palace Entrance (North)'
|
||||
entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
must_exits.append('Desert Palace Entrance (West)')
|
||||
dp_must_exit = 'Desert Palace Entrance (West)'
|
||||
entrances.append('Desert Palace Entrance (North)')
|
||||
|
||||
caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3)))
|
||||
@@ -1567,7 +1559,7 @@ def link_inverted_entrances(world, player):
|
||||
|
||||
|
||||
#place must-exit caves
|
||||
connect_mandatory_exits(world, entrances, caves, must_exits, player, dp_must_exit)
|
||||
connect_mandatory_exits(world, entrances, caves, must_exits, player)
|
||||
|
||||
|
||||
# place old man, has limited options
|
||||
@@ -1630,8 +1622,8 @@ def link_inverted_entrances(world, player):
|
||||
# and rentering to find bomb shop. However appended list here is all those that we currently have
|
||||
# bomb shop logic for.
|
||||
# Specifically we could potentially add: 'Dark Death Mountain Ledge (East)' and doors associated with pits
|
||||
bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + ['Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance'])
|
||||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
|
||||
bomb_shop_doors = list(Inverted_Bomb_Shop_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + ['Turtle Rock Isolated Ledge Entrance', 'Hookshot Cave Back Entrance'])
|
||||
blacksmith_doors = list(Inverted_Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors)
|
||||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
|
||||
random.shuffle(doors)
|
||||
@@ -1940,17 +1932,33 @@ def connect_random(world, exitlist, targetlist, player, two_way=False):
|
||||
connect_entrance(world, exit, target, player)
|
||||
|
||||
|
||||
def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, dp_must_exit=None):
|
||||
def connect_mandatory_exits(world, entrances, caves, must_be_exits, player):
|
||||
"""This works inplace"""
|
||||
random.shuffle(entrances)
|
||||
random.shuffle(caves)
|
||||
# Keeps track of entrances that cannot be used to access each exit / cave
|
||||
if world.mode == 'inverted':
|
||||
invalid_connections = Inverted_Must_Exit_Invalid_Connections.copy()
|
||||
else:
|
||||
invalid_connections = Must_Exit_Invalid_Connections.copy()
|
||||
invalid_cave_connections = defaultdict(set)
|
||||
|
||||
# Handle inverted Aga Tower - if it depends on connections, then so does Hyrule Castle Ledge
|
||||
if world.mode == 'inverted':
|
||||
for entrance in invalid_connections:
|
||||
if world.get_entrance(entrance, player).connected_region == world.get_region('Inverted Agahnims Tower', player):
|
||||
for exit in invalid_connections[entrance]:
|
||||
invalid_connections[exit] = invalid_connections[exit].union({'Inverted Ganons Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'})
|
||||
break
|
||||
|
||||
used_caves = []
|
||||
required_entrances = 0 # Number of entrances reserved for used_caves
|
||||
while must_be_exits:
|
||||
exit = must_be_exits.pop()
|
||||
# find multi exit cave
|
||||
cave = None
|
||||
for candidate in caves:
|
||||
if not isinstance(candidate, str):
|
||||
if not isinstance(candidate, str) and (candidate in used_caves or len(candidate) < len(entrances) - required_entrances - 1):
|
||||
cave = candidate
|
||||
break
|
||||
|
||||
@@ -1959,30 +1967,47 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, dp_m
|
||||
|
||||
# all caves are sorted so that the last exit is always reachable
|
||||
connect_two_way(world, exit, cave[-1], player)
|
||||
if len(cave) == 2:
|
||||
entrance = entrances.pop()
|
||||
# ToDo Better solution, this is a hot fix. Do not connect both sides of trock/desert ledge only to each other
|
||||
if world.mode[player] != 'inverted' and entrance == 'Dark Death Mountain Ledge (West)':
|
||||
new_entrance = entrances.pop()
|
||||
entrances.append(entrance)
|
||||
entrance = new_entrance
|
||||
if world.mode[player] == 'inverted' and entrance == dp_must_exit:
|
||||
new_entrance = entrances.pop()
|
||||
entrances.append(entrance)
|
||||
entrance = new_entrance
|
||||
if len(cave) == 2:
|
||||
entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit] and e not in invalid_cave_connections[tuple(cave)])
|
||||
entrances.remove(entrance)
|
||||
connect_two_way(world, entrance, cave[0], player)
|
||||
if cave in used_caves:
|
||||
required_entrances -= 2
|
||||
used_caves.remove(cave)
|
||||
if entrance in invalid_connections:
|
||||
for exit2 in invalid_connections[entrance]:
|
||||
invalid_connections[exit2] = invalid_connections[exit2].union(invalid_connections[exit]).union(invalid_cave_connections[tuple(cave)])
|
||||
elif cave[-1] == 'Spectacle Rock Cave Exit': #Spectacle rock only has one exit
|
||||
for exit in cave[:-1]:
|
||||
connect_two_way(world,entrances.pop(),exit, player)
|
||||
cave_entrances = []
|
||||
for cave_exit in cave[:-1]:
|
||||
entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit])
|
||||
cave_entrances.append(entrance)
|
||||
entrances.remove(entrance)
|
||||
connect_two_way(world,entrance,cave_exit, player)
|
||||
if entrance not in invalid_connections:
|
||||
invalid_connections[exit] = set()
|
||||
if all(entrance in invalid_connections for entrance in cave_entrances):
|
||||
new_invalid_connections = invalid_connections[cave_entrances[0]].intersection(invalid_connections[cave_entrances[1]])
|
||||
for exit2 in new_invalid_connections:
|
||||
invalid_connections[exit2] = invalid_connections[exit2].union(invalid_connections[exit])
|
||||
else:#save for later so we can connect to multiple exits
|
||||
if cave in used_caves:
|
||||
required_entrances -= 1
|
||||
used_caves.remove(cave)
|
||||
else:
|
||||
required_entrances += len(cave)-1
|
||||
caves.append(cave[0:-1])
|
||||
random.shuffle(caves)
|
||||
used_caves.append(cave[0:-1])
|
||||
invalid_cave_connections[tuple(cave[0:-1])] = invalid_cave_connections[tuple(cave)].union(invalid_connections[exit])
|
||||
caves.remove(cave)
|
||||
for cave in used_caves:
|
||||
if cave in caves: #check if we placed multiple entrances from this 3 or 4 exit
|
||||
for exit in cave:
|
||||
connect_two_way(world, entrances.pop(), exit, player)
|
||||
for cave_exit in cave:
|
||||
entrance = next(e for e in entrances[::-1] if e not in invalid_cave_connections[tuple(cave)])
|
||||
invalid_cave_connections[tuple(cave)] = set()
|
||||
entrances.remove(entrance)
|
||||
connect_two_way(world, entrance, cave_exit, player)
|
||||
caves.remove(cave)
|
||||
|
||||
|
||||
@@ -2685,6 +2710,8 @@ Inverted_Bomb_Shop_Multi_Cave_Doors = ['Hyrule Castle Entrance (South)',
|
||||
'Desert Palace Entrance (West)',
|
||||
'Desert Palace Entrance (North)']
|
||||
|
||||
Inverted_Blacksmith_Multi_Cave_Doors = Blacksmith_Multi_Cave_Doors # same as non-inverted
|
||||
|
||||
Inverted_LW_Single_Cave_Doors = LW_Single_Cave_Doors + ['Inverted Big Bomb Shop']
|
||||
|
||||
Inverted_DW_Single_Cave_Doors = ['Bonk Fairy (Dark)',
|
||||
@@ -2755,6 +2782,37 @@ Inverted_Bomb_Shop_Single_Cave_Doors = ['Waterfall of Wishing',
|
||||
'Inverted Links House',
|
||||
'Inverted Big Bomb Shop']
|
||||
|
||||
Inverted_Blacksmith_Single_Cave_Doors = ['Blinds Hideout',
|
||||
'Lake Hylia Fairy',
|
||||
'Light Hype Fairy',
|
||||
'Desert Fairy',
|
||||
'Chicken House',
|
||||
'Aginahs Cave',
|
||||
'Sahasrahlas Hut',
|
||||
'Cave Shop (Lake Hylia)',
|
||||
'Blacksmiths Hut',
|
||||
'Sick Kids House',
|
||||
'Lost Woods Gamble',
|
||||
'Fortune Teller (Light)',
|
||||
'Snitch Lady (East)',
|
||||
'Snitch Lady (West)',
|
||||
'Bush Covered House',
|
||||
'Tavern (Front)',
|
||||
'Light World Bomb Hut',
|
||||
'Kakariko Shop',
|
||||
'Mini Moldorm Cave',
|
||||
'Long Fairy Cave',
|
||||
'Good Bee Cave',
|
||||
'20 Rupee Cave',
|
||||
'50 Rupee Cave',
|
||||
'Ice Rod Cave',
|
||||
'Library',
|
||||
'Potion Shop',
|
||||
'Dam',
|
||||
'Lumberjack House',
|
||||
'Lake Hylia Fortune Teller',
|
||||
'Kakariko Gamble Game',
|
||||
'Inverted Big Bomb Shop']
|
||||
|
||||
Inverted_Single_Cave_Targets = ['Blinds Hideout',
|
||||
'Bonk Fairy (Light)',
|
||||
@@ -2844,6 +2902,27 @@ Isolated_LH_Doors = ['Kings Grave',
|
||||
'Dark World Hammer Peg Cave',
|
||||
'Turtle Rock Isolated Ledge Entrance']
|
||||
|
||||
# Entrances that cannot be used to access a must_exit entrance - symmetrical to allow reverse lookups
|
||||
Must_Exit_Invalid_Connections = defaultdict(set, {
|
||||
'Dark Death Mountain Ledge (East)': {'Dark Death Mountain Ledge (West)', 'Mimic Cave'},
|
||||
'Dark Death Mountain Ledge (West)': {'Dark Death Mountain Ledge (East)', 'Mimic Cave'},
|
||||
'Mimic Cave': {'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)'},
|
||||
'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'},
|
||||
'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'},
|
||||
'Skull Woods Second Section Door (West)': {'Skull Woods Final Section'},
|
||||
'Skull Woods Final Section': {'Skull Woods Second Section Door (West)'},
|
||||
})
|
||||
Inverted_Must_Exit_Invalid_Connections = defaultdict(set, {
|
||||
'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'},
|
||||
'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'},
|
||||
'Desert Palace Entrance (North)': {'Desert Palace Entrance (West)'},
|
||||
'Desert Palace Entrance (West)': {'Desert Palace Entrance (North)'},
|
||||
'Inverted Ganons Tower': {'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'},
|
||||
'Hyrule Castle Entrance (West)': {'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower'},
|
||||
'Hyrule Castle Entrance (East)': {'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower'},
|
||||
})
|
||||
|
||||
|
||||
# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions
|
||||
mandatory_connections = [('Links House S&Q', 'Links House'),
|
||||
('Sanctuary S&Q', 'Sanctuary'),
|
||||
@@ -2879,8 +2958,10 @@ inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'),
|
||||
('Old Man S&Q', 'Old Man House'),
|
||||
('Castle Ledge S&Q', 'Hyrule Castle Ledge'),
|
||||
('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'),
|
||||
('Lake Hylia Island', 'Lake Hylia Island'),
|
||||
('Zoras River', 'Zoras River'),
|
||||
('Lake Hylia Island Pier', 'Lake Hylia Island'),
|
||||
('Lake Hylia Warp', 'Northeast Light World'),
|
||||
('Northeast Light World Warp', 'Light World'),
|
||||
('Zoras River', 'Zoras River'),
|
||||
('Kings Grave Outer Rocks', 'Kings Grave Area'),
|
||||
('Kings Grave Inner Rocks', 'Light World'),
|
||||
('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'),
|
||||
|
||||
13
Fill.py
13
Fill.py
@@ -377,6 +377,19 @@ def flood_items(world):
|
||||
break
|
||||
|
||||
|
||||
def lock_shop_locations(world, player):
|
||||
for shop, loc_names in shop_to_location_table.items():
|
||||
for loc in loc_names:
|
||||
world.get_location(loc, player).event = True
|
||||
world.get_location(loc, player).locked = True
|
||||
# I don't believe these locations exist in non-shopsanity
|
||||
# if world.retro[player]:
|
||||
# for shop, loc_names in retro_shops.items():
|
||||
# for loc in loc_names:
|
||||
# world.get_location(loc, player).event = True
|
||||
# world.get_location(loc, player).locked = True
|
||||
|
||||
|
||||
def sell_potions(world, player):
|
||||
loc_choices = []
|
||||
for shop in world.shops[player]:
|
||||
|
||||
@@ -11,7 +11,7 @@ def create_inverted_regions(world, player):
|
||||
["Blinds Hideout", "Hyrule Castle Secret Entrance Drop", 'Kings Grave Outer Rocks', 'Dam',
|
||||
'Inverted Big Bomb Shop', 'Tavern North', 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Kakariko Well Drop', 'Kakariko Well Cave',
|
||||
'Blacksmiths Hut', 'Bat Cave Drop Ledge', 'Bat Cave Cave', 'Sick Kids House', 'Hobo Bridge', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump',
|
||||
'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier', 'Lake Hylia Island',
|
||||
'Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Mini Moldorm Cave', 'Ice Rod Cave', 'Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia Warp',
|
||||
'Bonk Rock Cave', 'Library', 'Two Brothers House (East)', 'Desert Palace Stairs', 'Eastern Palace', 'Master Sword Meadow',
|
||||
'Sanctuary', 'Sanctuary Grave', 'Death Mountain Entrance Rock', 'Light World River Drop',
|
||||
'Elder House (East)', 'Elder House (West)', 'North Fairy Cave', 'North Fairy Cave Drop', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Tavern (Front)',
|
||||
@@ -30,7 +30,7 @@ def create_inverted_regions(world, player):
|
||||
"Blind\'s Hideout - Right",
|
||||
"Blind\'s Hideout - Far Left",
|
||||
"Blind\'s Hideout - Far Right"]),
|
||||
create_lw_region(player, 'Northeast Light World', None, ['Zoras River', 'Waterfall of Wishing', 'Potion Shop Outer Rock', 'Northeast Dark World Mirror Spot']),
|
||||
create_lw_region(player, 'Northeast Light World', None, ['Zoras River', 'Waterfall of Wishing', 'Potion Shop Outer Rock', 'Northeast Dark World Mirror Spot', 'Northeast Light World Warp']),
|
||||
create_lw_region(player, 'Potion Shop Area', None, ['Potion Shop', 'Potion Shop Inner Bushes', 'Potion Shop Inner Rock', 'Potion Shop Mirror Spot', 'Potion Shop River Drop']),
|
||||
create_lw_region(player, 'Graveyard Cave Area', None, ['Graveyard Cave', 'Graveyard Cave Inner Bushes', 'Graveyard Cave Mirror Spot']),
|
||||
create_lw_region(player, 'River', None, ['Light World Pier', 'Potion Shop Pier']),
|
||||
|
||||
63
ItemList.py
63
ItemList.py
@@ -37,7 +37,7 @@ Difficulty = namedtuple('Difficulty',
|
||||
['baseitems', 'bottles', 'bottle_count', 'same_bottle', 'progressiveshield',
|
||||
'basicshield', 'progressivearmor', 'basicarmor', 'swordless',
|
||||
'progressivesword', 'basicsword', 'basicbow', 'timedohko', 'timedother',
|
||||
'triforcehunt', 'triforce_pieces_required', 'retro',
|
||||
'retro',
|
||||
'extras', 'progressive_sword_limit', 'progressive_shield_limit',
|
||||
'progressive_armor_limit', 'progressive_bottle_limit',
|
||||
'progressive_bow_limit', 'heart_piece_limit', 'boss_heart_container_limit'])
|
||||
@@ -60,8 +60,6 @@ difficulties = {
|
||||
basicbow = ['Bow', 'Silver Arrows'],
|
||||
timedohko = ['Green Clock'] * 25,
|
||||
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt = ['Triforce Piece'] * 30,
|
||||
triforce_pieces_required = 20,
|
||||
retro = ['Small Key (Universal)'] * 18 + ['Rupees (20)'] * 10,
|
||||
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit = 4,
|
||||
@@ -87,8 +85,6 @@ difficulties = {
|
||||
basicbow = ['Bow'] * 2,
|
||||
timedohko = ['Green Clock'] * 25,
|
||||
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt = ['Triforce Piece'] * 30,
|
||||
triforce_pieces_required = 20,
|
||||
retro = ['Small Key (Universal)'] * 13 + ['Rupees (5)'] * 15,
|
||||
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit = 3,
|
||||
@@ -114,8 +110,6 @@ difficulties = {
|
||||
basicbow = ['Bow'] * 2,
|
||||
timedohko = ['Green Clock'] * 20 + ['Red Clock'] * 5,
|
||||
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt = ['Triforce Piece'] * 30,
|
||||
triforce_pieces_required = 20,
|
||||
retro = ['Small Key (Universal)'] * 13 + ['Rupees (5)'] * 15,
|
||||
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit = 2,
|
||||
@@ -198,7 +192,6 @@ def generate_itempool(world, player):
|
||||
region = world.get_region('Hyrule Castle Courtyard',player)
|
||||
|
||||
loc = Location(player, "Murahdahla", parent=region)
|
||||
loc.access_rule = lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= state.world.treasure_hunt_count[player]
|
||||
region.locations.append(loc)
|
||||
world.dynamic_locations.append(loc)
|
||||
|
||||
@@ -262,7 +255,7 @@ def generate_itempool(world, player):
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.customitemarray)
|
||||
world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999)
|
||||
else:
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.doorShuffle[player])
|
||||
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.doorShuffle[player])
|
||||
|
||||
if player in world.pool_adjustment.keys():
|
||||
amt = world.pool_adjustment[player]
|
||||
@@ -286,7 +279,7 @@ def generate_itempool(world, player):
|
||||
if not found_sword and world.swords[player] != 'swordless':
|
||||
found_sword = True
|
||||
possible_weapons.append(item)
|
||||
if item in ['Progressive Bow', 'Bow'] and not found_bow:
|
||||
if item in ['Progressive Bow', 'Bow'] and not found_bow and not world.retro[player]:
|
||||
found_bow = True
|
||||
possible_weapons.append(item)
|
||||
if item in ['Hammer', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']:
|
||||
@@ -320,10 +313,14 @@ def generate_itempool(world, player):
|
||||
if clock_mode is not None:
|
||||
world.clock_mode = clock_mode
|
||||
|
||||
if treasure_hunt_count is not None:
|
||||
world.treasure_hunt_count[player] = treasure_hunt_count
|
||||
if treasure_hunt_icon is not None:
|
||||
world.treasure_hunt_icon[player] = treasure_hunt_icon
|
||||
if world.goal[player] == 'triforcehunt':
|
||||
if world.treasure_hunt_count[player] == 0:
|
||||
world.treasure_hunt_count[player] = 20
|
||||
if world.treasure_hunt_total[player] == 0:
|
||||
world.treasure_hunt_total[player] = 30
|
||||
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
||||
if world.custom:
|
||||
world.treasure_hunt_count[player] = treasure_hunt_count
|
||||
|
||||
world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player
|
||||
and ((item.smallkey and world.keyshuffle[player])
|
||||
@@ -511,6 +508,8 @@ def set_up_shops(world, player):
|
||||
shop.add_inventory(1, 'Small Key (Universal)', 100)
|
||||
shop.add_inventory(2, 'Bombs (10)', 50)
|
||||
rss.locked = True
|
||||
cap_shop = world.get_region('Capacity Upgrade', player).shop
|
||||
cap_shop.inventory[1] = None # remove arrow capacity upgrades in retro
|
||||
|
||||
|
||||
def customize_shops(world, player):
|
||||
@@ -576,7 +575,6 @@ def customize_shops(world, player):
|
||||
loc.item = upgrade
|
||||
upgrade.location = loc
|
||||
change_shop_items_to_rupees(world, player, shops_to_customize)
|
||||
todays_discounts(world, player)
|
||||
|
||||
|
||||
def randomize_price(price):
|
||||
@@ -598,7 +596,7 @@ def randomize_price(price):
|
||||
def change_shop_items_to_rupees(world, player, shops):
|
||||
locations = world.get_filled_locations(player)
|
||||
for location in locations:
|
||||
if location.item.name in shop_transfer.keys() and location.parent_region.name not in shops:
|
||||
if location.item.name in shop_transfer.keys() and (location.parent_region.name not in shops or location.name == 'Potion Shop'):
|
||||
new_item = ItemFactory(shop_transfer[location.item.name], location.item.player)
|
||||
location.item = new_item
|
||||
if location.parent_region.name == 'Capacity Upgrade' and location.item.name in cap_blacklist:
|
||||
@@ -609,19 +607,6 @@ def change_shop_items_to_rupees(world, player, shops):
|
||||
shop.add_inventory(slot, new_item.name, randomize_price(new_item.price), 1, player=new_item.player)
|
||||
|
||||
|
||||
def todays_discounts(world, player):
|
||||
locs = []
|
||||
for shop, locations in shop_to_location_table.items():
|
||||
for slot, loc in enumerate(locations):
|
||||
locs.append((world.get_location(loc, player), shop, slot))
|
||||
discount_number = random.randint(4, 7)
|
||||
chosen_locations = random.choices(locs, k=discount_number)
|
||||
for location, shop_name, slot in chosen_locations:
|
||||
shop = world.get_region(shop_name, player).shop
|
||||
orig = location.item.price
|
||||
shop.inventory[slot]['price'] = randomize_price(orig // 5)
|
||||
|
||||
|
||||
repeatable_shop_items = ['Single Arrow', 'Arrows (10)', 'Bombs (3)', 'Bombs (10)', 'Red Potion', 'Small Heart',
|
||||
'Blue Shield', 'Red Shield', 'Bee', 'Small Key (Universal)', 'Blue Potion', 'Green Potion']
|
||||
|
||||
@@ -631,20 +616,22 @@ cap_replacements = ['Single Arrow', 'Arrows (10)', 'Bombs (3)', 'Bombs (10)']
|
||||
|
||||
cap_blacklist = ['Green Potion', 'Red Potion', 'Blue Potion']
|
||||
|
||||
shop_transfer = {'Red Potion': 'Rupees (100)', 'Bee': 'Rupees (5)', 'Blue Potion': 'Rupees (100)',
|
||||
shop_transfer = {'Red Potion': 'Rupees (50)', 'Bee': 'Rupees (5)', 'Blue Potion': 'Rupees (50)',
|
||||
'Green Potion': 'Rupees (50)',
|
||||
# money seems a bit too generous with these on
|
||||
# 'Blue Shield': 'Rupees (50)', 'Red Shield': 'Rupees (300)',
|
||||
}
|
||||
|
||||
|
||||
def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, door_shuffle):
|
||||
def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, door_shuffle):
|
||||
pool = []
|
||||
placed_items = {}
|
||||
precollected_items = []
|
||||
clock_mode = None
|
||||
treasure_hunt_count = None
|
||||
treasure_hunt_icon = None
|
||||
if goal == 'triforcehunt':
|
||||
if treasure_hunt_total == 0:
|
||||
treasure_hunt_total = 30
|
||||
triforcepool = ['Triforce Piece'] * int(treasure_hunt_total)
|
||||
|
||||
pool.extend(alwaysitems)
|
||||
|
||||
@@ -738,13 +725,13 @@ def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, r
|
||||
extraitems -= len(diff.timedohko)
|
||||
clock_mode = 'countdown-ohko'
|
||||
if goal == 'triforcehunt':
|
||||
pool.extend(diff.triforcehunt)
|
||||
extraitems -= len(diff.triforcehunt)
|
||||
treasure_hunt_count = diff.triforce_pieces_required
|
||||
treasure_hunt_icon = 'Triforce Piece'
|
||||
pool.extend(triforcepool)
|
||||
extraitems -= len(triforcepool)
|
||||
|
||||
for extra in diff.extras:
|
||||
if extraitems > 0:
|
||||
if len(extra) > extraitems:
|
||||
extra = random.choices(extra, k=extraitems)
|
||||
pool.extend(extra)
|
||||
extraitems -= len(extra)
|
||||
|
||||
@@ -769,7 +756,7 @@ def get_pool_core(progressive, shuffle, difficulty, timer, goal, mode, swords, r
|
||||
pool.extend(['Small Key (Universal)'])
|
||||
else:
|
||||
pool.extend(['Small Key (Universal)'])
|
||||
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms)
|
||||
return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms)
|
||||
|
||||
def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, customitemarray):
|
||||
if isinstance(customitemarray,dict) and 1 in customitemarray:
|
||||
|
||||
56
Items.py
56
Items.py
@@ -65,8 +65,8 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
||||
'Blue Pendant': (True, False, 'Crystal', [0x02, 0x34, 0x60, 0x00, 0x69, 0x02], 999, None, None, None, None, None, None, None),
|
||||
'Red Pendant': (True, False, 'Crystal', [0x01, 0x32, 0x60, 0x00, 0x69, 0x03], 999, None, None, None, None, None, None, None),
|
||||
'Triforce': (True, False, None, 0x6A, 777, '\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, 50, '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, 50, 'a small victory', 'and the thirdforce', 'triangular kid', 'triangle for sale', 'fungus for triangle', 'wise boy has triangle again', 'a Triforce Piece'),
|
||||
'Power Star': (True, False, None, 0x6B, 100, '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, 100, '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], 999, None, None, None, None, None, None, None),
|
||||
'Crystal 2': (True, False, 'Crystal', [0x10, 0x34, 0x64, 0x40, 0x79, 0x06], 999, None, None, None, None, None, None, None),
|
||||
'Crystal 3': (True, False, 'Crystal', [0x40, 0x34, 0x64, 0x40, 0x6C, 0x06], 999, None, None, None, None, None, None, None),
|
||||
@@ -111,56 +111,56 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche
|
||||
'Multi RNG': (False, True, None, 0x63, 100, 'something you may already have', None, None, None, None, 'unknown boy somethings again', 'a total mystery'),
|
||||
'Magic Upgrade (1/2)': (True, False, None, 0x4E, 50, '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, 100, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Eastern Palace)': (False, False, 'SmallKey', 0xA2, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Desert Palace)': (False, False, 'SmallKey', 0xA3, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Tower of Hera)': (False, False, 'SmallKey', 0xAA, 40, '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, 60, '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, 10, '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, 20, '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 (Escape)': (False, False, 'SmallKey', 0xA0, 30, '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 (Escape)': (False, False, 'BigKey', 0x9F, 50, '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'),
|
||||
'Small Key (Escape)': (False, False, 'SmallKey', 0xA0, 40, '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 (Escape)': (False, False, 'BigKey', 0x9F, 60, '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 (Escape)': (False, True, 'Compass', 0x8F, 10, 'Now you can find no boss!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds null again', 'a compass to Hyrule Castle'),
|
||||
'Map (Escape)': (False, True, 'Map', 0x7F, 10, '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, 30, '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'),
|
||||
'Big Key (Agahnims Tower)': (False, False, 'BigKey', 0x9B, 50, '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'),
|
||||
'Small Key (Agahnims Tower)': (False, False, 'SmallKey', 0xA4, 40, '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'),
|
||||
'Big Key (Agahnims Tower)': (False, False, 'BigKey', 0x9B, 60, '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, 10, '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, 10, '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'),
|
||||
'Small Key (Palace of Darkness)': (False, False, 'SmallKey', 0xA6, 30, '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, 50, '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'),
|
||||
'Small Key (Palace of Darkness)': (False, False, 'SmallKey', 0xA6, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Thieves Town)': (False, False, 'SmallKey', 0xAB, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Skull Woods)': (False, False, 'SmallKey', 0xA8, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Swamp Palace)': (False, False, 'SmallKey', 0xA5, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Ice Palace)': (False, False, 'SmallKey', 0xA9, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Misery Mire)': (False, False, 'SmallKey', 0xA7, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Turtle Rock)': (False, False, 'SmallKey', 0xAC, 40, '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, 60, '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, 10, '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, 20, '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, 30, '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, 50, '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'),
|
||||
'Small Key (Ganons Tower)': (False, False, 'SmallKey', 0xAD, 40, '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, 60, '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, 10, 'Now you can find Agahnim!', 'and the compass', 'the magnetic kid', 'compass for sale', 'magnetic fungus', 'compass boy finds boss again', 'a comapss to Ganon\'s Tower'),
|
||||
'Map (Ganons Tower)': (False, True, 'Map', 0x72, 10, '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, 100, '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'),
|
||||
|
||||
15
Main.py
15
Main.py
@@ -24,11 +24,11 @@ from RoomData import create_rooms
|
||||
from Rules import set_rules
|
||||
from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive
|
||||
from Fill import distribute_items_cutoff, distribute_items_staleness, distribute_items_restrictive, flood_items
|
||||
from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression
|
||||
from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations
|
||||
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
|
||||
from Utils import output_path, parse_player_names
|
||||
|
||||
__version__ = '0.3.1.0-u'
|
||||
__version__ = '0.3.1.7-u'
|
||||
|
||||
|
||||
class EnemizerError(RuntimeError):
|
||||
@@ -42,6 +42,9 @@ def main(args, seed=None, fish=None):
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
# if args.securerandom:
|
||||
# random.use_secure()
|
||||
|
||||
# initialize the world
|
||||
if args.code:
|
||||
for player, code in args.code.items():
|
||||
@@ -58,6 +61,9 @@ def main(args, seed=None, fish=None):
|
||||
world.seed = int(seed)
|
||||
random.seed(world.seed)
|
||||
|
||||
if args.securerandom:
|
||||
world.seed = None
|
||||
|
||||
world.remote_items = args.remote_items.copy()
|
||||
world.mapshuffle = args.mapshuffle.copy()
|
||||
world.compassshuffle = args.compassshuffle.copy()
|
||||
@@ -82,6 +88,8 @@ def main(args, seed=None, fish=None):
|
||||
world.keydropshuffle = args.keydropshuffle.copy()
|
||||
world.mixed_travel = args.mixed_travel.copy()
|
||||
world.standardize_palettes = args.standardize_palettes.copy()
|
||||
world.treasure_hunt_count = args.triforce_goal.copy()
|
||||
world.treasure_hunt_total = args.triforce_pool.copy()
|
||||
|
||||
world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)}
|
||||
|
||||
@@ -167,6 +175,9 @@ def main(args, seed=None, fish=None):
|
||||
sell_potions(world, player)
|
||||
if world.retro[player]:
|
||||
sell_keys(world, player)
|
||||
else:
|
||||
lock_shop_locations(world, player)
|
||||
|
||||
|
||||
logger.info(world.fish.translate("cli","cli","placing.dungeon.prizes"))
|
||||
|
||||
|
||||
16
Mystery.py
16
Mystery.py
@@ -126,6 +126,12 @@ def roll_settings(weights):
|
||||
return None
|
||||
return random.choices(list(root[option].keys()), weights=list(map(int,root[option].values())))[0]
|
||||
|
||||
def get_choice_default(option, root=weights, default=None):
|
||||
choice = get_choice(option, root)
|
||||
if choice is None and default is not None:
|
||||
return default
|
||||
return choice
|
||||
|
||||
ret = argparse.Namespace()
|
||||
|
||||
glitches_required = get_choice('glitches_required')
|
||||
@@ -175,7 +181,15 @@ def roll_settings(weights):
|
||||
ret.crystals_gt = get_choice('tower_open')
|
||||
|
||||
ret.crystals_ganon = get_choice('ganon_open')
|
||||
|
||||
|
||||
if ret.goal == 'triforcehunt':
|
||||
goal_min = get_choice_default('triforce_goal_min', default=20)
|
||||
goal_max = get_choice_default('triforce_goal_max', default=20)
|
||||
pool_min = get_choice_default('triforce_pool_min', default=30)
|
||||
pool_max = get_choice_default('triforce_pool_max', default=30)
|
||||
ret.triforce_goal = random.randint(int(goal_min), int(goal_max))
|
||||
min_diff = get_choice_default('triforce_min_difference', default=10)
|
||||
ret.triforce_pool = random.randint(max(int(pool_min), ret.triforce_goal + int(min_diff)), int(pool_max))
|
||||
ret.mode = get_choice('world_state')
|
||||
if ret.mode == 'retro':
|
||||
ret.mode = 'open'
|
||||
|
||||
@@ -51,6 +51,7 @@ All prices range approx. from half the base price to the base price in increment
|
||||
| Major Progression | Hammer, Hookshot, Mirror, Ocarina, Boots, Somaria, Fire Rod, Ice Rod | 250 | 125-250
|
||||
| | Moon Pearl | 200 | 100-200
|
||||
| | Lamp, Progressive Bows, Gloves, & Swords | 150 | 75-150
|
||||
| | Triforce Piece | 100 | 50-100
|
||||
| Medallions | Bombos, Ether, Quake | 100 | 50-100
|
||||
| Safety/Fetch | Cape, Mushroom, Shovel, Powder, Bug Net, Byrna, Progressive Armor & Shields, Half Magic | 50 | 25-50
|
||||
| Bottles | Empty Bottle or Bee Bottle | 50 | 25-50
|
||||
@@ -60,8 +61,8 @@ All prices range approx. from half the base price to the base price in increment
|
||||
| Health | Heart Container | 40 | 20-40
|
||||
| | Sanctuary Heart | 50 | 25-50
|
||||
| | Piece of Heart | 10 | 5-10
|
||||
| Dungeon | Big Keys | 50 | 25-50
|
||||
| | Small Keys | 30 | 15-30
|
||||
| Dungeon | Big Keys | 60 | 30-60
|
||||
| | Small Keys | 40 | 20-40
|
||||
| | Info Maps | 20 | 10-20
|
||||
| | Other Maps & Compasses | 10 | 5-10
|
||||
| Rupees | Green | Free | Free
|
||||
@@ -74,7 +75,7 @@ All prices range approx. from half the base price to the base price in increment
|
||||
| | Single Arrow | 3 | 3
|
||||
| Original Shop Items | Other Ammo, Refills, Non-Progressive Shields, Capacity Upgrades, Small Hearts, Retro Quiver, Universal Key | Original | Could be Discounted as Above
|
||||
|
||||
In addition, 4-7 items are steeply discounted at random.
|
||||
~~In addition, 4-7 items are steeply discounted at random.~~ Sales are over.
|
||||
|
||||
#### Rupee Balancing Algorithm
|
||||
|
||||
@@ -122,12 +123,62 @@ Added to CLI only now. With more testing, this will be added to the GUI to be ab
|
||||
The Mystery.py file has been updated for those who like to use that for generating games. Supports keydropshuffle,
|
||||
shopsanity, and other settings that have been added.
|
||||
|
||||
## Triforce Hunt Options
|
||||
|
||||
Thanks to deathFouton!
|
||||
|
||||
--triforce_pool and --triforce_goal added to the CLI.
|
||||
|
||||
Also, to the Mystery.py he added the following options:
|
||||
* triforce_goal_min
|
||||
* triforce_goal_max
|
||||
* triforce_pool_min
|
||||
* triforce_pool_max
|
||||
* triforce_min_difference
|
||||
|
||||
See the example yaml file for demonstrated usage.
|
||||
|
||||
## Experimental Item Counter
|
||||
|
||||
New item counter modified to show total
|
||||
|
||||
# Bug Fixes and Notes.
|
||||
|
||||
* 0.3.1.7-u
|
||||
* TFH counter off in modes where it should be off
|
||||
* Fixed Big Bomb logic for inverted (bad merge)
|
||||
* Updated pip requirements for MultiClient
|
||||
* Updated local_install.py and instructions (Thanks MikeTrethewey)
|
||||
* 0.3.1.6-u
|
||||
* Fix for inverted. AT or GT vanilla lobby in intensity 3 should not softlock on exit in non-ER modes.
|
||||
* Backward compatibility for "chaos" enemizer flags. (Thanks krebel)
|
||||
* Fix for potshuffle and swamp trench generation errors (Thanks StructuralMike)
|
||||
* Fix for TFH playthrough (Thanks StructuralMike)
|
||||
* Fix for Standard+Retro (Thanks StructuralMike)
|
||||
* New options for TFH in CLI and Mystery (Thanks deathFouton)
|
||||
* A few price adjustments for Shopsanity
|
||||
* Fixed a subtle problem with Progressive Shields introduced by Shopsanity
|
||||
* 0.3.1.5-u
|
||||
* Ganon hints fixed for shops
|
||||
* Added support for a settings file so SahasrahBot and the main website can use it easier. (Thanks Synack)
|
||||
* Fix for Skull Pinball during re-generation attempts (thank compiling)
|
||||
* Fix for multiworld progression balancing and shopsanity
|
||||
* 0.3.1.4-u
|
||||
* Fix for Blind when shuffled to TT and another dungeon
|
||||
* Remove use of RaceRandom
|
||||
* Minor update to GameType field
|
||||
* 0.3.1.3-u
|
||||
* Fix for the Rom field on the GUI
|
||||
* 0.3.1.2-u
|
||||
* Include base ER updates
|
||||
* Goal sign should now indicate whether Aga 2 is required or not
|
||||
* Inverted logic fixes
|
||||
* Potion shop (powder) item now properly replaced with rupees
|
||||
* Removed Arrow Capacity upgrades in retro (non-shopsanity)
|
||||
* Intensity level 3 fixes courtesy of Catobat
|
||||
* Scrolling issue in Desert Cannonball
|
||||
* 0.3.1.1-u
|
||||
* Potion shop crash in non-shopsanity
|
||||
* 0.3.1.0-u
|
||||
* Shopsanity introduced
|
||||
* Blind sequence restored when Blind is in Theives Town in boss shuffle
|
||||
|
||||
44
RaceRandom.py
Normal file
44
RaceRandom.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import random as _random
|
||||
from functools import update_wrapper
|
||||
|
||||
__all__ = ["use_secure"]
|
||||
|
||||
_prng_inst = _random.Random()
|
||||
_cprng_inst = _random.SystemRandom()
|
||||
|
||||
_mode = "prng"
|
||||
|
||||
def use_secure(secure=True):
|
||||
# pylint: disable=global-statement
|
||||
global _mode
|
||||
_mode = "cprng" if secure else "prng"
|
||||
|
||||
def _wrap(name):
|
||||
def somefunc(*args, **kwargs):
|
||||
return getattr(_cprng_inst if _mode == "cprng" else _prng_inst, name)(*args, **kwargs)
|
||||
update_wrapper(somefunc, getattr(_prng_inst, name))
|
||||
|
||||
return somefunc
|
||||
|
||||
# These are for intellisense purposes only, and will be overwritten below
|
||||
choice = _prng_inst.choice
|
||||
gauss = _prng_inst.gauss
|
||||
getrandbits = _prng_inst.getrandbits
|
||||
randint = _prng_inst.randint
|
||||
random = _prng_inst.random
|
||||
randrange = _prng_inst.randrange
|
||||
sample = _prng_inst.sample
|
||||
seed = _prng_inst.seed
|
||||
shuffle = _prng_inst.shuffle
|
||||
uniform = _prng_inst.uniform
|
||||
|
||||
for func_name in dir(_random):
|
||||
if not callable(getattr(_random, func_name)):
|
||||
continue
|
||||
if not callable(getattr(_prng_inst, func_name, None)):
|
||||
continue
|
||||
if func_name.startswith('_'):
|
||||
continue
|
||||
|
||||
globals()[func_name] = _wrap(func_name)
|
||||
__all__.append(func_name)
|
||||
66
Rom.py
66
Rom.py
@@ -16,7 +16,7 @@ from BaseClasses import CollectionState, ShopType, Region, Location, OWEdge, Doo
|
||||
from DoorShuffle import compass_data, DROptions, boss_indicator
|
||||
from Dungeons import dungeon_music_addresses
|
||||
from KeyDoorShuffle import count_locations_exclude_logic
|
||||
from Regions import location_table
|
||||
from Regions import location_table, shop_to_location_table
|
||||
from RoomData import DoorKind
|
||||
from Text import MultiByteTextMapper, CompressedTextMapper, text_addresses, Credits, TextTable
|
||||
from Text import Uncle_texts, Ganon1_texts, TavernMan_texts, Sahasrahla2_texts, Triforce_texts, Blind_texts, BombShop2_texts, junk_texts
|
||||
@@ -312,8 +312,10 @@ def patch_enemizer(world, player, rom, baserom_path, enemizercli, random_sprite_
|
||||
|
||||
if world.get_dungeon("Thieves Town", player).boss.enemizer_name == "Blind":
|
||||
rom.write_byte(0x04DE81, 0x6) # maiden spawn
|
||||
# restore blind spawn code
|
||||
rom.write_bytes(0xEA081, [0xaf, 0xcc, 0xf3, 0x7e, 0xc9, 0x6, 0xf0, 0x24,
|
||||
# restore blind spawn code - necessary because the old enemizer clobbers this stuff
|
||||
# this line could be commented out if ijwu's enemizer is used exclusively
|
||||
# if keeping this line, note the jump to the dr_baserom's enemizer section
|
||||
rom.write_bytes(0xEA081, [0x5c, 0x00, 0x80, 0xb7, 0xc9, 0x6, 0xf0, 0x24,
|
||||
0xad, 0x3, 0x4, 0x29, 0x20, 0xf0, 0x1d])
|
||||
rom.write_byte(0x200101, 0) # Do not close boss room door on entry.
|
||||
|
||||
@@ -736,6 +738,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
aga_portal = world.get_portal('Agahnims Tower', player)
|
||||
gt_portal = world.get_portal('Ganons Tower', player)
|
||||
aga_portal.exit_offset, gt_portal.exit_offset = gt_portal.exit_offset, aga_portal.exit_offset
|
||||
aga_portal.default = False
|
||||
gt_portal.default = False
|
||||
|
||||
for portal in world.dungeon_portals[player]:
|
||||
if not portal.default:
|
||||
@@ -1122,17 +1126,18 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
|
||||
# set up goals for treasure hunt
|
||||
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28])
|
||||
rom.write_byte(0x180167, world.treasure_hunt_count[player] % 256)
|
||||
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
||||
if world.goal[player] == 'triforcehunt':
|
||||
rom.write_byte(0x180167, int(world.treasure_hunt_count[player]) % 256)
|
||||
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
||||
|
||||
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
|
||||
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
|
||||
|
||||
gametype = 0x04 # item
|
||||
if world.shuffle[player] != 'vanilla':
|
||||
gametype |= 0x02 # entrance
|
||||
if world.shuffle[player] != 'vanilla' or world.doorShuffle[player] != 'vanilla' or world.keydropshuffle[player]:
|
||||
gametype |= 0x02 # entrance/door
|
||||
if enemized:
|
||||
gametype |= 0x01 # enemizer
|
||||
rom.write_byte(0x180211, gametype) # Game type
|
||||
gametype |= 0x01 # enemizer
|
||||
rom.write_byte(0x180211, gametype) # Game type
|
||||
|
||||
# assorted fixes
|
||||
rom.write_byte(0x1800A2, 0x01) # remain in real dark world when dying in dark world dungeon before killing aga1
|
||||
@@ -1351,6 +1356,14 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_byte(0x13f0f6+x, room.position(portal.door).value)
|
||||
rom.write_byte(0x13f0f7+x, room.kind(portal.door).value)
|
||||
|
||||
# Bitfield - enable text box to show with free roaming items
|
||||
#
|
||||
# ---o bmcs
|
||||
# o - enabled for outside dungeon items
|
||||
# b - enabled for inside big keys
|
||||
# m - enabled for inside maps
|
||||
# c - enabled for inside compasses
|
||||
# s - enabled for inside small keys
|
||||
rom.write_byte(0x18016A, 0x10 | ((0x01 if world.keyshuffle[player] else 0x00)
|
||||
| (0x02 if world.compassshuffle[player] else 0x00)
|
||||
| (0x04 if world.mapshuffle[player] else 0x00)
|
||||
@@ -1367,6 +1380,14 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
else:
|
||||
rom.write_byte(0x18003C, 0x00)
|
||||
|
||||
# Bitfield - enable free items to show up in menu
|
||||
#
|
||||
# ----dcba
|
||||
# d - Compass
|
||||
# c - Map
|
||||
# b - Big Key
|
||||
# a - Small Key
|
||||
#
|
||||
rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] else 0x00)
|
||||
| (0x02 if world.bigkeyshuffle[player] else 0x00)
|
||||
| (0x04 if world.mapshuffle[player] else 0x00)
|
||||
@@ -1468,7 +1489,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_bytes(0x02F539, [0xEA, 0xEA, 0xEA, 0xEA, 0xEA] if world.powder_patch_required[player] else [0xAD, 0xBF, 0x0A, 0xF0, 0x4F])
|
||||
|
||||
# allow smith into multi-entrance caves in appropriate shuffles
|
||||
if world.shuffle[player] in ['restricted', 'full', 'crossed', 'insanity']:
|
||||
if world.shuffle[player] in ['restricted', 'full', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'):
|
||||
rom.write_byte(0x18004C, 0x01)
|
||||
|
||||
# set correct flag for hera basement item
|
||||
@@ -1559,7 +1580,10 @@ def write_custom_shops(rom, world, player):
|
||||
break
|
||||
if world.shopsanity[player] or shop.type == ShopType.TakeAny:
|
||||
rom.write_byte(0x186560 + shop.sram_address + index, 1)
|
||||
item_id = ItemFactory(item['item'], player).code
|
||||
loc_item = world.get_location(shop_to_location_table[shop.region.name][index], player).item
|
||||
if not loc_item:
|
||||
loc_item = ItemFactory(item['item'], player)
|
||||
item_id = loc_item.code
|
||||
price = int16_as_bytes(item['price'])
|
||||
replace = ItemFactory(item['replacement'], player).code if item['replacement'] else 0xFF
|
||||
replace_price = int16_as_bytes(item['replacement_price'])
|
||||
@@ -2007,16 +2031,16 @@ def write_strings(rom, world, player, team):
|
||||
|
||||
prog_bow_locs = world.find_items('Progressive Bow', player)
|
||||
distinguished_prog_bow_loc = next((location for location in prog_bow_locs if location.item.code == 0x65), None)
|
||||
progressive_silvers = world.difficulty_requirements[player].progressive_bow_limit >= 2 or world.swords[player] == 'swordless'
|
||||
if distinguished_prog_bow_loc:
|
||||
prog_bow_locs.remove(distinguished_prog_bow_loc)
|
||||
silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s', 'my'))
|
||||
silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s', 'my')) if progressive_silvers else '?\nI think not!'
|
||||
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||
|
||||
if any(prog_bow_locs):
|
||||
silverarrow_hint = (' %s?' % hint_text(random.choice(prog_bow_locs)).replace('Ganon\'s', 'my'))
|
||||
silverarrow_hint = (' %s?' % hint_text(random.choice(prog_bow_locs)).replace('Ganon\'s', 'my')) if progressive_silvers else '?\nI think not!'
|
||||
tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||
|
||||
|
||||
crystal5 = world.find_items('Crystal 5', player)[0]
|
||||
crystal6 = world.find_items('Crystal 6', player)[0]
|
||||
tt['bomb_shop'] = 'Big Bomb?\nMy supply is blocked until you clear %s and %s.' % (crystal5.hint_text, crystal6.hint_text)
|
||||
@@ -2025,7 +2049,15 @@ def write_strings(rom, world, player, team):
|
||||
tt['sahasrahla_bring_courage'] = 'I lost my family heirloom in %s' % greenpendant.hint_text
|
||||
|
||||
tt['sign_ganons_tower'] = ('You need %d crystal to enter.' if world.crystals_needed_for_gt[player] == 1 else 'You need %d crystals to enter.') % world.crystals_needed_for_gt[player]
|
||||
tt['sign_ganon'] = ('You need %d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else 'You need %d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player]
|
||||
|
||||
ganon_crystals_singular = 'You need %d crystal to beat Ganon.'
|
||||
ganon_crystals_plural = 'You need %d crystals to beat Ganon.'
|
||||
|
||||
if world.goal[player] == 'ganon':
|
||||
ganon_crystals_singular = 'To beat Ganon you must collect %d crystal and defeat his minion at the top of his tower.'
|
||||
ganon_crystals_plural = 'To beat Ganon you must collect %d crystals and defeat his minion at the top of his tower.'
|
||||
|
||||
tt['sign_ganon'] = (ganon_crystals_singular if world.crystals_needed_for_ganon[player] == 1 else ganon_crystals_plural) % world.crystals_needed_for_ganon[player]
|
||||
|
||||
if world.goal[player] in ['dungeons']:
|
||||
tt['sign_ganon'] = 'You need to complete all the dungeons.'
|
||||
@@ -2042,7 +2074,7 @@ def write_strings(rom, world, player, team):
|
||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.'
|
||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||
tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!'
|
||||
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % world.treasure_hunt_count[player]
|
||||
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % int(world.treasure_hunt_count[player])
|
||||
elif world.goal[player] in ['pedestal']:
|
||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.'
|
||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||
|
||||
98
Rules.py
98
Rules.py
@@ -41,6 +41,8 @@ def set_rules(world, player):
|
||||
elif world.goal[player] == 'ganon':
|
||||
# require aga2 to beat ganon
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||
elif world.goal[player] == 'triforcehunt':
|
||||
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
||||
|
||||
if world.mode[player] != 'inverted':
|
||||
set_big_bomb_rules(world, player)
|
||||
@@ -689,7 +691,9 @@ def inverted_rules(world, player):
|
||||
|
||||
set_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player))
|
||||
set_rule(world.get_entrance('Waterfall of Wishing', player), lambda state: state.has('Flippers', player) and state.has_Pearl(player)) # can be fake flippered into, but is in weird state inside that might prevent you from doing things. Can be improved in future Todo
|
||||
set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) or (state.can_reach('Light World', 'Region', player) and state.has_Mirror(player)))
|
||||
set_rule(world.get_location('Frog', player), lambda state: state.can_lift_heavy_rocks(player) and
|
||||
(state.has_Pearl(player) or state.has('Beat Agahnim 1', player)) or (state.can_reach('Light World', 'Region', player)
|
||||
and state.has_Mirror(player))) # Need LW access using Mirror or Portal
|
||||
set_rule(world.get_location('Mushroom', player), lambda state: state.has_Pearl(player)) # need pearl to pick up bushes
|
||||
set_rule(world.get_entrance('Bush Covered Lawn Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Bush Covered Lawn Inner Bushes', player), lambda state: state.has_Pearl(player))
|
||||
@@ -728,7 +732,6 @@ def inverted_rules(world, player):
|
||||
set_rule(world.get_entrance('Village of Outcasts Heavy Rock', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
set_rule(world.get_entrance('East Dark World Bridge', player), lambda state: state.has('Hammer', player))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('East Dark World River Pier', player), lambda state: state.has('Flippers', player)) # ToDo any fake flipper set up? (Qirn Jump)
|
||||
set_rule(world.get_entrance('Bumper Cave Entrance Rock', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Hammer Peg Area Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -807,7 +810,9 @@ def no_glitches_rules(world, player):
|
||||
else:
|
||||
add_rule(world.get_entrance('Zoras River', player), lambda state: state.has_Pearl(player) and (state.has('Flippers', player) or state.can_lift_rocks(player)))
|
||||
add_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # can be fake flippered to
|
||||
add_rule(world.get_entrance('Lake Hylia Island', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
|
||||
add_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # can be fake flippered to
|
||||
set_rule(world.get_entrance('Lake Hylia Warp', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # can be fake flippered to
|
||||
set_rule(world.get_entrance('Northeast Light World Warp', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player)) # can be fake flippered to
|
||||
add_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has_Pearl(player) and state.has('Flippers', player))
|
||||
add_rule(world.get_entrance('Dark Lake Hylia Drop (East)', player), lambda state: state.has('Flippers', player))
|
||||
add_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player) and (state.has('Hammer', player) or state.can_lift_rocks(player)))
|
||||
@@ -1308,6 +1313,7 @@ def set_big_bomb_rules(world, player):
|
||||
# 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)))
|
||||
|
||||
|
||||
def set_inverted_big_bomb_rules(world, player):
|
||||
bombshop_entrance = world.get_region('Inverted Big Bomb Shop', player).entrances[0]
|
||||
Normal_LW_entrances = ['Blinds Hideout',
|
||||
@@ -1358,33 +1364,35 @@ def set_inverted_big_bomb_rules(world, player):
|
||||
'Cave 45',
|
||||
'Checkerboard Cave',
|
||||
'Inverted Big Bomb Shop']
|
||||
LW_DM_entrances = ['Old Man Cave (East)',
|
||||
'Old Man House (Bottom)',
|
||||
'Old Man House (Top)',
|
||||
'Death Mountain Return Cave (East)',
|
||||
'Spectacle Rock Cave Peak',
|
||||
'Tower of Hera',
|
||||
'Death Mountain Return Cave (West)',
|
||||
'Paradox Cave (Top)',
|
||||
'Fairy Ascension Cave (Top)',
|
||||
'Spiral Cave',
|
||||
'Paradox Cave (Bottom)',
|
||||
'Paradox Cave (Middle)',
|
||||
'Hookshot Fairy',
|
||||
'Spiral Cave (Bottom)',
|
||||
'Mimic Cave',
|
||||
'Fairy Ascension Cave (Bottom)',
|
||||
'Desert Palace Entrance (West)',
|
||||
'Desert Palace Entrance (North)',
|
||||
'Desert Palace Entrance (South)']
|
||||
Isolated_LW_entrances = ['Old Man Cave (East)',
|
||||
'Old Man House (Bottom)',
|
||||
'Old Man House (Top)',
|
||||
'Death Mountain Return Cave (East)',
|
||||
'Spectacle Rock Cave Peak',
|
||||
'Tower of Hera',
|
||||
'Death Mountain Return Cave (West)',
|
||||
'Paradox Cave (Top)',
|
||||
'Fairy Ascension Cave (Top)',
|
||||
'Spiral Cave',
|
||||
'Paradox Cave (Bottom)',
|
||||
'Paradox Cave (Middle)',
|
||||
'Hookshot Fairy',
|
||||
'Spiral Cave (Bottom)',
|
||||
'Mimic Cave',
|
||||
'Fairy Ascension Cave (Bottom)',
|
||||
'Desert Palace Entrance (West)',
|
||||
'Desert Palace Entrance (North)',
|
||||
'Desert Palace Entrance (South)']
|
||||
Eastern_DW_entrances = ['Palace of Darkness',
|
||||
'Palace of Darkness Hint',
|
||||
'Dark Lake Hylia Fairy',
|
||||
'East Dark World Hint']
|
||||
Northern_DW_entrances = ['Brewery',
|
||||
'C-Shaped House',
|
||||
'Chest Game',
|
||||
'Dark World Hammer Peg Cave',
|
||||
'Red Shield Shop',
|
||||
'Inverted Dark Sanctuary',
|
||||
'Fortune Teller (Dark)',
|
||||
'Dark World Shop',
|
||||
'Dark World Lumberjack Shop',
|
||||
'Thieves Town',
|
||||
'Skull Woods First Section Door',
|
||||
@@ -1409,19 +1417,26 @@ def set_inverted_big_bomb_rules(world, player):
|
||||
'Hookshot Cave',
|
||||
'Turtle Rock Isolated Ledge Entrance',
|
||||
'Hookshot Cave Back Entrance',
|
||||
'Inverted Agahnims Tower',
|
||||
'Dark Lake Hylia Ledge Fairy',
|
||||
'Inverted Agahnims Tower',]
|
||||
LW_walkable_entrances = ['Dark Lake Hylia Ledge Fairy',
|
||||
'Dark Lake Hylia Ledge Spike Cave',
|
||||
'Dark Lake Hylia Ledge Hint',
|
||||
'Mire Shed',
|
||||
'Dark Desert Hint',
|
||||
'Dark Desert Fairy',
|
||||
'Misery Mire']
|
||||
'Misery Mire',
|
||||
'Red Shield Shop']
|
||||
LW_bush_entrances = ['Bush Covered House',
|
||||
'Light World Bomb Hut',
|
||||
'Graveyard Cave']
|
||||
LW_inaccessible_entrances = ['Desert Palace Entrance (East)',
|
||||
'Spectacle Rock Cave',
|
||||
'Spectacle Rock Cave (Bottom)']
|
||||
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('East Dark World', 'Region', player) and state.can_reach('Inverted Big Bomb Shop', 'Region', player) and state.has('Crystal 5', player) and state.has('Crystal 6', player))
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player),
|
||||
lambda state: state.can_reach('East Dark World', 'Region', player)
|
||||
and state.can_reach('Inverted Big Bomb Shop', 'Region', player)
|
||||
and state.has('Crystal 5', player) and state.has('Crystal 6', player))
|
||||
|
||||
# crossing peg bridge starting from the southern dark world
|
||||
def cross_peg_bridge(state):
|
||||
@@ -1433,25 +1448,38 @@ def set_inverted_big_bomb_rules(world, player):
|
||||
# H = hammer
|
||||
# M = Mirror
|
||||
# G = Glove
|
||||
if bombshop_entrance.name in Normal_LW_entrances:
|
||||
if bombshop_entrance.name in Eastern_DW_entrances:
|
||||
# Just walk to the pyramid
|
||||
pass
|
||||
elif bombshop_entrance.name in Normal_LW_entrances:
|
||||
# Just walk to the castle and mirror.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player))
|
||||
elif bombshop_entrance.name in LW_DM_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.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and state.has_Mirror(player))
|
||||
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,
|
||||
# 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 cross_peg_bridge(state)) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or
|
||||
(state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or
|
||||
(state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
||||
elif bombshop_entrance.name in Southern_DW_entrances:
|
||||
# This is the same as north DW without the Mitts rock present.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: cross_peg_bridge(state) or state.can_flute(player) or (state.has_Mirror(player) and state.can_reach('Light World', 'Region', player)))
|
||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||
# 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))
|
||||
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
|
||||
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)))
|
||||
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.
|
||||
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 cross_peg_bridge(state))))
|
||||
#todo: I stopped here -
|
||||
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
|
||||
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))))
|
||||
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.
|
||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute or (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (state.has_Mirror(player) and state.can_lift_rocks(player) and state.can_reach('Light World', 'Region', player)))
|
||||
@@ -1476,6 +1504,14 @@ def set_inverted_big_bomb_rules(world, player):
|
||||
elif bombshop_entrance.name == 'Capacity Upgrade':
|
||||
# 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))
|
||||
elif bombshop_entrance.name in LW_inaccessible_entrances:
|
||||
# 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)
|
||||
elif bombshop_entrance.name == 'Pyramid Fairy':
|
||||
# Self locking. The shuffles don't put the bomb shop here, but doesn't lock anything important.
|
||||
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False)
|
||||
else:
|
||||
raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name)
|
||||
|
||||
|
||||
def set_bunny_rules(world, player):
|
||||
|
||||
128
Utils.py
128
Utils.py
@@ -6,19 +6,24 @@ import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def int16_as_bytes(value):
|
||||
value = value & 0xFFFF
|
||||
return [value & 0xFF, (value >> 8) & 0xFF]
|
||||
|
||||
|
||||
def int32_as_bytes(value):
|
||||
value = value & 0xFFFFFFFF
|
||||
return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF]
|
||||
|
||||
|
||||
def pc_to_snes(value):
|
||||
return ((value<<1) & 0x7F0000)|(value & 0x7FFF)|0x8000
|
||||
return ((value << 1) & 0x7F0000) | (value & 0x7FFF) | 0x8000
|
||||
|
||||
|
||||
def snes_to_pc(value):
|
||||
return ((value & 0x7F0000)>>1)|(value & 0x7FFF)
|
||||
return ((value & 0x7F0000) >> 1) | (value & 0x7FFF)
|
||||
|
||||
|
||||
def parse_player_names(names, players, teams):
|
||||
names = [n for n in re.split(r'[, ]', names) if n]
|
||||
@@ -32,9 +37,11 @@ def parse_player_names(names, players, teams):
|
||||
names = names[players:]
|
||||
return ret
|
||||
|
||||
|
||||
def is_bundled():
|
||||
return getattr(sys, 'frozen', False)
|
||||
|
||||
|
||||
def local_path(path):
|
||||
# just do stuff here and bail
|
||||
return os.path.join(".", path)
|
||||
@@ -44,51 +51,26 @@ def local_path(path):
|
||||
|
||||
if is_bundled():
|
||||
# we are running in a bundle
|
||||
local_path.cached_path = sys._MEIPASS # pylint: disable=protected-access,no-member
|
||||
local_path.cached_path = sys._MEIPASS # pylint: disable=protected-access,no-member
|
||||
else:
|
||||
# we are running in a normal Python environment
|
||||
local_path.cached_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
return os.path.join(local_path.cached_path, path)
|
||||
|
||||
|
||||
local_path.cached_path = None
|
||||
|
||||
|
||||
def output_path(path):
|
||||
# just do stuff here and bail
|
||||
return os.path.join(".", path)
|
||||
|
||||
if output_path.cached_path is not None:
|
||||
return os.path.join(output_path.cached_path, path)
|
||||
|
||||
if not is_bundled():
|
||||
if output_path.cached_path is None:
|
||||
output_path.cached_path = '.'
|
||||
return os.path.join(output_path.cached_path, path)
|
||||
else:
|
||||
# has been packaged, so cannot use CWD for output.
|
||||
if sys.platform == 'win32':
|
||||
#windows
|
||||
documents = os.path.join(os.path.expanduser("~"),"Documents")
|
||||
elif sys.platform == 'darwin':
|
||||
from AppKit import NSSearchPathForDirectoriesInDomains # pylint: disable=import-error
|
||||
# http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
|
||||
NSDocumentDirectory = 9
|
||||
NSUserDomainMask = 1
|
||||
# True for expanding the tilde into a fully qualified path
|
||||
documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, True)[0]
|
||||
elif sys.platform.find("linux") or sys.platform.find("ubuntu") or sys.platform.find("unix"):
|
||||
documents = os.path.join(os.path.expanduser("~"),"Documents")
|
||||
else:
|
||||
raise NotImplementedError('Not supported yet')
|
||||
return os.path.join(output_path.cached_path, path)
|
||||
|
||||
output_path.cached_path = os.path.join(documents, 'ALttPDoorRandomizer')
|
||||
if not os.path.exists(output_path.cached_path):
|
||||
os.makedirs(output_path.cached_path)
|
||||
if not os.path.join(output_path.cached_path, path):
|
||||
os.makedirs(os.path.join(output_path.cached_path, path))
|
||||
return os.path.join(output_path.cached_path, path)
|
||||
|
||||
output_path.cached_path = None
|
||||
|
||||
|
||||
def open_file(filename):
|
||||
if sys.platform == 'win32':
|
||||
os.startfile(filename)
|
||||
@@ -96,15 +78,17 @@ def open_file(filename):
|
||||
open_command = 'open' if sys.platform == 'darwin' else 'xdg-open'
|
||||
subprocess.call([open_command, filename])
|
||||
|
||||
|
||||
def close_console():
|
||||
if sys.platform == 'win32':
|
||||
#windows
|
||||
# windows
|
||||
import ctypes.wintypes
|
||||
try:
|
||||
ctypes.windll.kernel32.FreeConsole()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def make_new_base2current(old_rom='Zelda no Densetsu - Kamigami no Triforce (Japan).sfc', new_rom='working.sfc'):
|
||||
from collections import OrderedDict
|
||||
import json
|
||||
@@ -125,7 +109,7 @@ def make_new_base2current(old_rom='Zelda no Densetsu - Kamigami no Triforce (Jap
|
||||
if offset - 1 in out_data:
|
||||
out_data[offset-1].extend(out_data.pop(offset))
|
||||
with open('data/base2current.json', 'wt') as outfile:
|
||||
json.dump([{key:value} for key, value in out_data.items()], outfile, separators=(",", ":"))
|
||||
json.dump([{key: value} for key, value in out_data.items()], outfile, separators=(",", ":"))
|
||||
|
||||
basemd5 = hashlib.md5()
|
||||
basemd5.update(new_rom_data)
|
||||
@@ -241,7 +225,6 @@ def room_palette_data(old_rom):
|
||||
print(f'{hex(header_offset)}: {[hex(x) for x in rooms]}')
|
||||
|
||||
|
||||
|
||||
# Palette notes:
|
||||
# HC: 0
|
||||
# Sewer/Dungeon: 1
|
||||
@@ -303,21 +286,22 @@ def print_wiki_doors_by_region(d_regions, world, player):
|
||||
toprint += ('| '+'<br />'.join(strs_to_print))
|
||||
toprint += "\n"
|
||||
toprint += ('|}') + "\n"
|
||||
with open(os.path.join(".","resources", "user", "regions-" + d + ".txt"),"w+") as f:
|
||||
with open(os.path.join(".", "resources", "user", "regions-" + d + ".txt"), "w+") as f:
|
||||
f.write(toprint)
|
||||
|
||||
|
||||
def update_deprecated_args(args):
|
||||
if args:
|
||||
argVars = vars(args)
|
||||
truthy = [ 1, True, "True", "true" ]
|
||||
truthy = [1, True, "True", "true"]
|
||||
# Hints default to TRUE
|
||||
# Don't do: Yes
|
||||
# Do: No
|
||||
if "no_hints" in argVars:
|
||||
src = "no_hints"
|
||||
if isinstance(argVars["hints"],dict):
|
||||
if isinstance(argVars["hints"], dict):
|
||||
tmp = {}
|
||||
for idx in range(1,len(argVars["hints"]) + 1):
|
||||
for idx in range(1, len(argVars["hints"]) + 1):
|
||||
tmp[idx] = argVars[src] not in truthy # tmp = !src
|
||||
args.hints = tmp # dest = tmp
|
||||
else:
|
||||
@@ -326,23 +310,23 @@ def update_deprecated_args(args):
|
||||
# Do: Yes
|
||||
if "hints" in argVars:
|
||||
src = "hints"
|
||||
if isinstance(argVars["hints"],dict):
|
||||
if isinstance(argVars["hints"], dict):
|
||||
tmp = {}
|
||||
for idx in range(1,len(argVars["hints"]) + 1):
|
||||
for idx in range(1, len(argVars["hints"]) + 1):
|
||||
tmp[idx] = argVars[src] not in truthy # tmp = !src
|
||||
args.no_hints = tmp # dest = tmp
|
||||
else:
|
||||
args.no_hints = args.hints not in truthy # dest = !src
|
||||
|
||||
# Spoiler defaults to FALSE
|
||||
# Don't do: No
|
||||
# Do: Yes
|
||||
if "create_spoiler" in argVars:
|
||||
args.suppress_spoiler = not args.create_spoiler in truthy
|
||||
# Spoiler defaults to TRUE
|
||||
# Don't do: Yes
|
||||
# Do: No
|
||||
if "suppress_spoiler" in argVars:
|
||||
args.create_spoiler = not args.suppress_spoiler in truthy
|
||||
# Don't do: No
|
||||
# Do: Yes
|
||||
if "create_spoiler" in argVars:
|
||||
args.suppress_spoiler = not args.create_spoiler in truthy
|
||||
|
||||
# ROM defaults to TRUE
|
||||
# Don't do: Yes
|
||||
@@ -376,6 +360,7 @@ def update_deprecated_args(args):
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def print_wiki_doors_by_room(d_regions, world, player):
|
||||
for d, region_list in d_regions.items():
|
||||
tile_map = {}
|
||||
@@ -407,14 +392,15 @@ def print_wiki_doors_by_room(d_regions, world, player):
|
||||
toprint += ('|-') + "\n"
|
||||
toprint += ('! Door !! Room Side !! Requirement') + "\n"
|
||||
for ext in region.exits:
|
||||
ext_part = ext.name.replace(region.name,'')
|
||||
ext_part = ext.name.replace(region.name, '')
|
||||
ext_part = ext_part.strip()
|
||||
toprint += ('{{DungeonRoomDoorList/Row|{{ROOTPAGENAME}}|{{SUBPAGENAME}}|' + ext_part + '|Side|}}') + "\n"
|
||||
toprint += ('|}') + "\n"
|
||||
toprint += ('') + "\n"
|
||||
with open(os.path.join(".","resources", "user", "rooms-" + d + ".txt"),"w+") as f:
|
||||
with open(os.path.join(".", "resources", "user", "rooms-" + d + ".txt"), "w+") as f:
|
||||
f.write(toprint)
|
||||
|
||||
|
||||
def print_xml_doors(d_regions, world, player):
|
||||
root = ET.Element('root')
|
||||
for d, region_list in d_regions.items():
|
||||
@@ -459,7 +445,8 @@ def extract_data_from_us_rom(rom):
|
||||
with open(rom, 'rb') as stream:
|
||||
rom_data = bytearray(stream.read())
|
||||
|
||||
rooms = [0x9a, 0x69, 0x78, 0x79, 0x7a, 0x88, 0x8a, 0xad]
|
||||
rooms = [0x1c, 0x1d, 0x4e]
|
||||
# rooms = [0x9a, 0x69, 0x78, 0x79, 0x7a, 0x88, 0x8a, 0xad]
|
||||
for room in rooms:
|
||||
b2idx = room*2
|
||||
b3idx = room*3
|
||||
@@ -470,11 +457,20 @@ def extract_data_from_us_rom(rom):
|
||||
header.append(rom_data[headerloc+i])
|
||||
objectptr = 0xF8000 + b3idx
|
||||
objectloc = rom_data[objectptr] + rom_data[objectptr+1]*0x100 + rom_data[objectptr+2]*0x10000
|
||||
objectloc -= 0x100000
|
||||
bank = rom_data[objectptr+2]
|
||||
even = bank % 2 == 0
|
||||
adjustment = ((bank // 2 if even else bank // 2 + 1) << 16) + (0x8000 if even else 0)
|
||||
objectloc -= adjustment
|
||||
stop, idx = False, 0
|
||||
ffcnt = 0
|
||||
mode = 0
|
||||
while ffcnt < 2:
|
||||
# first two bytes
|
||||
b1 = rom_data[objectloc+idx]
|
||||
b2 = rom_data[objectloc+idx+1]
|
||||
objectdata.append(b1)
|
||||
objectdata.append(b2)
|
||||
idx += 2
|
||||
while ffcnt < 3:
|
||||
b1 = rom_data[objectloc+idx]
|
||||
b2 = rom_data[objectloc+idx+1]
|
||||
b3 = rom_data[objectloc+idx+2]
|
||||
@@ -483,9 +479,11 @@ def extract_data_from_us_rom(rom):
|
||||
if b1 == 0xff and b2 == 0xff:
|
||||
ffcnt += 1
|
||||
mode = 0
|
||||
if b1 == 0xf0 and b2 == 0xff:
|
||||
idx += 2
|
||||
elif b1 == 0xf0 and b2 == 0xff:
|
||||
mode = 1
|
||||
if not mode and ffcnt < 2:
|
||||
idx += 2
|
||||
elif not mode and ffcnt < 3:
|
||||
objectdata.append(b3)
|
||||
idx += 3
|
||||
else:
|
||||
@@ -573,8 +571,9 @@ def extract_data_from_jp_rom(rom):
|
||||
with open(rom, 'rb') as stream:
|
||||
rom_data = bytearray(stream.read())
|
||||
|
||||
rooms = [0x1c, 0x1d, 0x4e]
|
||||
# rooms = [0x7b, 0x7c, 0x7d, 0x8b, 0x8c, 0x8d, 0x9b, 0x9c, 0x9d]
|
||||
rooms = [0x1a, 0x2a, 0xd1]
|
||||
# rooms = [0x1a, 0x2a, 0xd1]
|
||||
for room in rooms:
|
||||
b2idx = room*2
|
||||
b3idx = room*3
|
||||
@@ -585,11 +584,20 @@ def extract_data_from_jp_rom(rom):
|
||||
header.append(rom_data[headerloc+i])
|
||||
objectptr = 0xF8000 + b3idx
|
||||
objectloc = rom_data[objectptr] + rom_data[objectptr+1]*0x100 + rom_data[objectptr+2]*0x10000
|
||||
objectloc -= 0x100000
|
||||
bank = rom_data[objectptr+2]
|
||||
even = bank % 2 == 0
|
||||
adjustment = ((bank // 2 if even else bank // 2 + 1) << 16) + (0x8000 if even else 0)
|
||||
objectloc -= adjustment
|
||||
stop, idx = False, 0
|
||||
ffcnt = 0
|
||||
mode = 0
|
||||
while ffcnt < 2:
|
||||
# first two bytes
|
||||
b1 = rom_data[objectloc+idx]
|
||||
b2 = rom_data[objectloc+idx+1]
|
||||
objectdata.append(b1)
|
||||
objectdata.append(b2)
|
||||
idx += 2
|
||||
while ffcnt < 3:
|
||||
b1 = rom_data[objectloc+idx]
|
||||
b2 = rom_data[objectloc+idx+1]
|
||||
b3 = rom_data[objectloc+idx+2]
|
||||
@@ -598,9 +606,11 @@ def extract_data_from_jp_rom(rom):
|
||||
if b1 == 0xff and b2 == 0xff:
|
||||
ffcnt += 1
|
||||
mode = 0
|
||||
if b1 == 0xf0 and b2 == 0xff:
|
||||
idx += 2
|
||||
elif b1 == 0xf0 and b2 == 0xff:
|
||||
mode = 1
|
||||
if not mode and ffcnt < 2:
|
||||
idx += 2
|
||||
elif not mode and ffcnt < 3:
|
||||
objectdata.append(b3)
|
||||
idx += 3
|
||||
else:
|
||||
|
||||
1
_config.yml
Normal file
1
_config.yml
Normal file
@@ -0,0 +1 @@
|
||||
theme: jekyll-theme-slate
|
||||
@@ -1,13 +1,19 @@
|
||||
# Running from source
|
||||
|
||||
1. Get [python](http://python.org/downloads)
|
||||
1. Get the [Door Randomizer Unstable source code](https://github.com/Aerinon/ALttPDoorRandomizer/archive/DoorDevUnstable.zip)
|
||||
1. Install Platform-specific dependencies
|
||||
1. Run `DoorRandomizer.py` for command-line script
|
||||
1. Run `Gui.py` for user interface
|
||||
|Instruction|Image|
|
||||
|-----------|-----|
|
||||
|Get [python](http://python.org/downloads)|
|
||||
|Get the [Door Randomizer Unstable source code](https://github.com/Aerinon/ALttPDoorRandomizer/archive/DoorDevUnstable.zip)|
|
||||
|Install Platform-specific dependencies (see below)|
|
||||
|Run `DungeonRandomizer.py` for command-line script|
|
||||
|Run `Gui.py` for user interface|
|
||||
|
||||
## Platform-specific dependencies
|
||||
|
||||
### Windows
|
||||
|
||||
* Run `resources/ci/common/local_install.py`
|
||||
|Platform|Command line|Image|
|
||||
| :----: |------------|-----|
|
||||
|Windows |`resources/ci/common/local_install.py`|
|
||||
|`py` Launcher: 3.9 |`resources/ci/common/local_install.py --py 3.9`|
|
||||
|`py` Launcher: 3.8 |`resources/ci/common/local_install.py --py 3.8`|
|
||||
|`py` Launcher: 3.7 |`resources/ci/common/local_install.py --py 3.7`|
|
||||
|`py` Launcher: 3.6 |`resources/ci/common/local_install.py --py 3.6`|
|
||||
|
||||
BIN
docs/images/cli-windows.png
Normal file
BIN
docs/images/cli-windows.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
BIN
docs/images/cmd.png
Normal file
BIN
docs/images/cmd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/images/py-dungeonrandomizer.png
Normal file
BIN
docs/images/py-dungeonrandomizer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
BIN
docs/images/py-gui.png
Normal file
BIN
docs/images/py-gui.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/images/python.png
Normal file
BIN
docs/images/python.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/images/sourcecode.png
Normal file
BIN
docs/images/sourcecode.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
@@ -39,11 +39,20 @@
|
||||
dungeons: 1
|
||||
pedestal: 2
|
||||
triforce-hunt: 0
|
||||
triforce_goal_min: 10
|
||||
triforce_goal_max: 30
|
||||
triforce_pool_min: 20
|
||||
triforce_pool_max: 40
|
||||
triforce_min_difference: 10
|
||||
dungeon_items:
|
||||
standard: 10
|
||||
mc: 3
|
||||
mcs: 2
|
||||
full: 5
|
||||
dungeon_counters:
|
||||
on: 5
|
||||
off: 0
|
||||
default: 5
|
||||
experimental:
|
||||
on: 1
|
||||
off: 0
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
"type": "bool"
|
||||
},
|
||||
"create_spoiler": {
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
"action": "store_false",
|
||||
"dest": "suppress_spoiler",
|
||||
"type": "bool",
|
||||
"help": "suppress"
|
||||
},
|
||||
"suppress_spoiler": {
|
||||
"action": "store_false",
|
||||
"dest": "create_spoiler",
|
||||
"help": "suppress"
|
||||
"action": "store_true"
|
||||
},
|
||||
"logic": {
|
||||
"choices": [
|
||||
@@ -226,6 +226,13 @@
|
||||
"usestartinventory": {
|
||||
"type": "bool"
|
||||
},
|
||||
"triforce_pool": {},
|
||||
"triforce_goal": {},
|
||||
"triforce_pool_min": {},
|
||||
"triforce_pool_max": {},
|
||||
"triforce_goal_min": {},
|
||||
"triforce_goal_max": {},
|
||||
"triforce_min_difference": {},
|
||||
"custom": {
|
||||
"type": "bool",
|
||||
"help": "suppress"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
aenum
|
||||
fast-enum
|
||||
python-bps-continued
|
||||
python-bps-continued
|
||||
colorama
|
||||
aioconsole
|
||||
websockets
|
||||
@@ -1,5 +1,7 @@
|
||||
import os # for env vars
|
||||
import stat # file statistics
|
||||
import sys # default system info
|
||||
from my_path import get_py_path
|
||||
|
||||
global UBUNTU_VERSIONS
|
||||
global DEFAULT_EVENT
|
||||
@@ -44,6 +46,8 @@ def prepare_env():
|
||||
APP_VERSION = f.readlines()[0].strip()
|
||||
# ci data
|
||||
env["CI_SYSTEM"] = os.getenv("CI_SYSTEM","")
|
||||
# py data
|
||||
(env["PYTHON_EXE_PATH"],env["PY_EXE_PATH"],env["PIP_EXE_PATH"]) = get_py_path()
|
||||
# git data
|
||||
env["BRANCH"] = os.getenv("TRAVIS_BRANCH","")
|
||||
env["GITHUB_ACTOR"] = os.getenv("GITHUB_ACTOR","MegaMan.EXE")
|
||||
@@ -75,10 +79,19 @@ def prepare_env():
|
||||
env["BUILD_NUMBER"] = os.getenv("TRAVIS_BUILD_NUMBER",env["GITHUB_RUN_NUMBER"])
|
||||
|
||||
GITHUB_TAG = os.getenv("TRAVIS_TAG",os.getenv("GITHUB_TAG",""))
|
||||
OS_NAME = os.getenv("TRAVIS_OS_NAME",os.getenv("OS_NAME","")).replace("macOS","osx")
|
||||
OS_NAME = os.getenv("TRAVIS_OS_NAME",os.getenv("OS_NAME",sys.platform)).replace("macOS","osx")
|
||||
OS_DIST = os.getenv("TRAVIS_DIST","notset")
|
||||
OS_VERSION = ""
|
||||
|
||||
if "win32" in OS_NAME or \
|
||||
"cygwin" in OS_NAME or \
|
||||
"msys" in OS_NAME:
|
||||
OS_NAME = "windows"
|
||||
elif "darwin" in OS_NAME:
|
||||
OS_NAME = "osx"
|
||||
elif "linux2" in OS_NAME:
|
||||
OS_NAME = "linux"
|
||||
|
||||
if '-' in OS_NAME:
|
||||
OS_VERSION = OS_NAME[OS_NAME.find('-')+1:]
|
||||
OS_NAME = OS_NAME[:OS_NAME.find('-')]
|
||||
|
||||
@@ -1,39 +1,63 @@
|
||||
import common
|
||||
import argparse
|
||||
import os
|
||||
import urllib.request, ssl
|
||||
import subprocess # do stuff at the shell level
|
||||
|
||||
env = common.prepare_env()
|
||||
|
||||
def get_get_pip():
|
||||
print("Getting pip getter!")
|
||||
#make the request!
|
||||
url = "https://bootstrap.pypa.io/get-pip.py"
|
||||
context = ssl._create_unverified_context()
|
||||
req = urllib.request.urlopen(url, context=context)
|
||||
got_pip = req.read().decode("utf-8")
|
||||
def get_get_pip(PY_VERSION):
|
||||
try:
|
||||
import pip
|
||||
except ImportError:
|
||||
print("Getting pip getter!")
|
||||
#make the request!
|
||||
url = "https://bootstrap.pypa.io/get-pip.py"
|
||||
context = ssl._create_unverified_context()
|
||||
req = urllib.request.urlopen(url, context=context)
|
||||
got_pip = req.read().decode("utf-8")
|
||||
|
||||
with open("get-pip.py", "w") as g:
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
data=None,
|
||||
headers={
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
|
||||
}
|
||||
)
|
||||
req = urllib.request.urlopen(req, context=context)
|
||||
data = req.read().decode("utf-8")
|
||||
g.write(data)
|
||||
with open("get-pip.py", "w") as g:
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
data=None,
|
||||
headers={
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
|
||||
}
|
||||
)
|
||||
req = urllib.request.urlopen(req, context=context)
|
||||
data = req.read().decode("utf-8")
|
||||
g.write(data)
|
||||
|
||||
# get executables
|
||||
# python
|
||||
# linux/windows: python
|
||||
# macosx: python3
|
||||
PYTHON_EXECUTABLE = "python3" if "osx" in env["OS_NAME"] else "python"
|
||||
print("Getting pip!")
|
||||
subprocess.check_call([PYTHON_EXECUTABLE,"get-pip.py"])
|
||||
# get executables
|
||||
# python
|
||||
# linux/windows: python
|
||||
# macosx: python3
|
||||
PYTHON_EXECUTABLE = "python3" if "osx" in env["OS_NAME"] else "python"
|
||||
if PY_VERSION == None:
|
||||
PY_VERSION = 0
|
||||
|
||||
if float(PY_VERSION) > 0:
|
||||
PYTHON_EXECUTABLE = "py"
|
||||
|
||||
print("Getting pip!")
|
||||
args = [
|
||||
env["PYTHON_EXE_PATH"] + PYTHON_EXECUTABLE,
|
||||
'-' + str(PY_VERSION),
|
||||
"get-pip.py"
|
||||
]
|
||||
if PY_VERSION == 0:
|
||||
del args[1]
|
||||
subprocess.check_call(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
import pip
|
||||
except ImportError:
|
||||
get_get_pip()
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument('--py', default=0)
|
||||
command_line_args = parser.parse_args()
|
||||
PY_VERSION = vars(command_line_args)["py"]
|
||||
|
||||
try:
|
||||
import pip
|
||||
print("pip is installed")
|
||||
except ImportError:
|
||||
get_get_pip(PY_VERSION)
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import common
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
import subprocess # do stuff at the shell level
|
||||
|
||||
env = common.prepare_env()
|
||||
|
||||
def run_install():
|
||||
pip_requirements = os.path.join(".","resources","app","meta","manifests","pip_requirements.txt")
|
||||
|
||||
def run_install(PY_VERSION,USER):
|
||||
# get executables
|
||||
# python
|
||||
# linux/windows: python
|
||||
@@ -11,20 +16,79 @@ def run_install():
|
||||
# pip
|
||||
# linux/macosx: pip3
|
||||
# windows: pip
|
||||
PYTHON_PATH = env["PYTHON_EXE_PATH"]
|
||||
PYTHON_EXECUTABLE = "python3" if "osx" in env["OS_NAME"] else "python"
|
||||
PIP_PATH = env["PIP_EXE_PATH"]
|
||||
PIP_EXECUTABLE = "pip" if "windows" in env["OS_NAME"] else "pip3"
|
||||
PIP_EXECUTABLE = "pip" if "osx" in env["OS_NAME"] and "actions" in env["CI_SYSTEM"] else PIP_EXECUTABLE
|
||||
|
||||
# upgrade pip
|
||||
subprocess.check_call([PYTHON_EXECUTABLE,"-m","pip","install","--upgrade","pip"])
|
||||
if PY_VERSION == None:
|
||||
PY_VERSION = 0
|
||||
if USER == None:
|
||||
USER = False
|
||||
|
||||
if float(PY_VERSION) > 0:
|
||||
PYTHON_EXECUTABLE = "py"
|
||||
PYTHON_PATH = env["PY_EXE_PATH"]
|
||||
print("Installing to Python %.1f via Py Launcher" % float(PY_VERSION))
|
||||
else:
|
||||
print("Installing to Python %s" % platform.python_version())
|
||||
print("Installing packages at %s level" % ("User" if USER else "Global"))
|
||||
|
||||
print()
|
||||
print("Upgrading pip-")
|
||||
# upgrade pip
|
||||
args = [
|
||||
PYTHON_PATH + PYTHON_EXECUTABLE,
|
||||
'-' + str(PY_VERSION),
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"--user",
|
||||
"pip"
|
||||
]
|
||||
if not USER:
|
||||
args.remove("--user")
|
||||
if PY_VERSION == 0:
|
||||
del args[1]
|
||||
subprocess.check_call(args)
|
||||
|
||||
# pip version
|
||||
subprocess.check_call([PIP_EXECUTABLE,"--version"])
|
||||
# if pip3, install wheel
|
||||
if PIP_EXECUTABLE == "pip3":
|
||||
subprocess.check_call([PIP_EXECUTABLE,"install","-U","wheel"])
|
||||
print("Installing Wheel!")
|
||||
args = [
|
||||
PIP_PATH + PIP_EXECUTABLE,
|
||||
"install",
|
||||
"--user",
|
||||
"-U",
|
||||
"wheel"
|
||||
]
|
||||
if not USER:
|
||||
args.remove("--user")
|
||||
subprocess.check_call(args)
|
||||
|
||||
print()
|
||||
# install listed dependencies
|
||||
subprocess.check_call([PIP_EXECUTABLE,"install","-r","./resources/app/meta/manifests/pip_requirements.txt"])
|
||||
print("Installing dependencies")
|
||||
print("-----------------------")
|
||||
args = [
|
||||
PIP_PATH + PIP_EXECUTABLE,
|
||||
"install",
|
||||
"--user",
|
||||
"-r",
|
||||
pip_requirements
|
||||
]
|
||||
if not USER:
|
||||
args.remove("--user")
|
||||
subprocess.check_call(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_install()
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument('--py', default=0)
|
||||
parser.add_argument('--user', default=False, action="store_true")
|
||||
command_line_args = parser.parse_args()
|
||||
PY_VERSION = vars(command_line_args)["py"]
|
||||
USER = vars(command_line_args)["user"]
|
||||
|
||||
run_install(PY_VERSION,USER)
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
import install
|
||||
import get_get_pip
|
||||
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument('--py', default=0)
|
||||
parser.add_argument('--user', default=False, action="store_true")
|
||||
command_line_args = parser.parse_args()
|
||||
PY_VERSION = vars(command_line_args)["py"]
|
||||
USER = vars(command_line_args)["user"]
|
||||
|
||||
# get & install pip
|
||||
get_get_pip.get_get_pip()
|
||||
get_get_pip.get_get_pip(PY_VERSION)
|
||||
|
||||
# run installer
|
||||
install.run_install()
|
||||
install.run_install(PY_VERSION,USER)
|
||||
|
||||
33
resources/ci/common/my_path.py
Normal file
33
resources/ci/common/my_path.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
def get_py_path():
|
||||
user_paths = os.environ["PATH"].split(os.pathsep)
|
||||
(python,py) = ("","")
|
||||
|
||||
for path in user_paths:
|
||||
parts = path.split(os.sep)
|
||||
part = parts[len(parts) - 1].lower()
|
||||
if ("python" in part) and ('.' not in part):
|
||||
path.replace(os.sep,os.sep + os.sep)
|
||||
if path not in user_paths:
|
||||
py = path
|
||||
|
||||
for path in sys.path:
|
||||
parts = path.split(os.sep)
|
||||
part = parts[len(parts) - 1].lower()
|
||||
if ("python" in part) and ('.' not in part):
|
||||
path.replace(os.sep,os.sep + os.sep)
|
||||
if path not in user_paths:
|
||||
python = path
|
||||
|
||||
paths = (
|
||||
os.path.join(python,"") if python != "" else "",
|
||||
os.path.join(py,"") if py != "" else "",
|
||||
os.path.join(python,"Scripts","") if python != "" else ""
|
||||
)
|
||||
# print(paths)
|
||||
return paths
|
||||
|
||||
if __name__ == "__main__":
|
||||
get_py_path()
|
||||
@@ -34,7 +34,7 @@ CUSTOMITEMLABELS = [
|
||||
"Ether", "Quake", "Lamp", "Hammer", "Shovel",
|
||||
|
||||
"Ocarina", "Bug Catching Net", "Book of Mudora", "Bottle", "Cane of Somaria",
|
||||
"Cane of Byrna", "Magic Cape", "Magic Mirror", "Pegasus Boots", "Power Glove",
|
||||
"Cane of Byrna", "Cape", "Magic Mirror", "Pegasus Boots", "Power Glove",
|
||||
"Titans Mitts", "Progressive Glove", "Flippers", "Moon Pearl", "Piece of Heart",
|
||||
|
||||
"Boss Heart Container", "Sanctuary Heart Container", "Fighter Sword", "Master Sword", "Tempered Sword",
|
||||
|
||||
@@ -7,6 +7,8 @@ import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
from Utils import output_path
|
||||
|
||||
def adjust_page(top, parent, settings):
|
||||
# Adjust page
|
||||
self = ttk.Frame(parent)
|
||||
@@ -90,6 +92,8 @@ def adjust_page(top, parent, settings):
|
||||
|
||||
# These are the options to Adjust
|
||||
def adjustRom():
|
||||
if output_path.cached_path is None:
|
||||
output_path.cached_path = top.settings["outputpath"]
|
||||
options = {
|
||||
"heartbeep": "heartbeep",
|
||||
"heartcolor": "heartcolor",
|
||||
|
||||
@@ -146,10 +146,13 @@ def bottom_frame(self, parent, args=None):
|
||||
self.widgets[widget].pieces["button"].pack(side=LEFT)
|
||||
|
||||
def open_output():
|
||||
if args and args.outputpath:
|
||||
open_file(output_path(args.outputpath))
|
||||
else:
|
||||
open_file(output_path(parent.settings["outputpath"]))
|
||||
if output_path.cached_path is None:
|
||||
if args and args.outputpath:
|
||||
output_path.cached_path = args.outputpath
|
||||
else:
|
||||
output_path.cached_path = parent.settings["outputpath"]
|
||||
|
||||
open_file(output_path('.'))
|
||||
|
||||
## Output Button
|
||||
# widget ID
|
||||
|
||||
@@ -66,7 +66,7 @@ def generation_page(parent,settings):
|
||||
# FIXME: Translate these
|
||||
def RomSelect():
|
||||
rom = filedialog.askopenfilename(filetypes=[("Rom Files", (".sfc", ".smc")), ("All Files", "*")], initialdir=os.path.join("."))
|
||||
self.widgets[widget].storageVar.set(rom)
|
||||
self.widgets["rom"].storageVar.set(rom)
|
||||
# dialog button
|
||||
self.widgets[widget].pieces["button"] = Button(self.widgets[widget].pieces["frame"], text='Select Rom', command=RomSelect)
|
||||
|
||||
|
||||
53
test/TestDeathMountain.py
Normal file
53
test/TestDeathMountain.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from BaseClasses import World
|
||||
from Dungeons import create_dungeons
|
||||
from EntranceShuffle import link_entrances
|
||||
from ItemList import difficulties
|
||||
from Regions import create_regions
|
||||
from Rules import set_rules
|
||||
from test.TestVanilla import TestVanilla
|
||||
|
||||
|
||||
class TestDeathMountain(TestVanilla):
|
||||
def setUp(self):
|
||||
self.world = World(1, 'vanilla', 'noglitches', 'open', 'random', 'normal', 'normal', 'none', 'on', 'ganon', 'balanced',
|
||||
True, False, False, False, False, False, False, False, False, None,
|
||||
'none', False)
|
||||
self.world.difficulty_requirements = difficulties['normal']
|
||||
create_regions(self.world, 1)
|
||||
create_dungeons(self.world, 1)
|
||||
link_entrances(self.world, 1)
|
||||
set_rules(self.world, 1)
|
||||
|
||||
def testWestDeathMountain(self):
|
||||
self.run_tests([
|
||||
["Ether Tablet", False, []],
|
||||
["Ether Tablet", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Ether Tablet", False, [], ['Lamp', 'Ocarina']],
|
||||
["Ether Tablet", False, [], ['Magic Mirror', 'Hookshot']],
|
||||
["Ether Tablet", False, [], ['Magic Mirror', 'Hammer']],
|
||||
["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||
["Ether Tablet", False, [], ['Book of Mudora']],
|
||||
["Ether Tablet", True, ['Ocarina', 'Magic Mirror', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||
["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Magic Mirror', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||
["Ether Tablet", True, ['Ocarina', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||
["Ether Tablet", True, ['Progressive Glove', 'Lamp', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||
|
||||
["Old Man", False, []],
|
||||
["Old Man", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Old Man", False, [], ['Lamp']],
|
||||
["Old Man", True, ['Ocarina', 'Lamp']],
|
||||
["Old Man", True, ['Progressive Glove', 'Lamp']],
|
||||
|
||||
["Spectacle Rock Cave", False, []],
|
||||
["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Spectacle Rock Cave", False, [], ['Lamp', 'Ocarina']],
|
||||
["Spectacle Rock Cave", True, ['Ocarina']],
|
||||
["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']],
|
||||
|
||||
["Spectacle Rock", False, []],
|
||||
["Spectacle Rock", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Spectacle Rock", False, [], ['Lamp', 'Ocarina']],
|
||||
["Spectacle Rock", False, [], ['Magic Mirror']],
|
||||
["Spectacle Rock", True, ['Ocarina', 'Magic Mirror']],
|
||||
["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Magic Mirror']],
|
||||
])
|
||||
41
test/TestVanilla.py
Normal file
41
test/TestVanilla.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import unittest
|
||||
|
||||
from BaseClasses import World, CollectionState
|
||||
from Dungeons import create_dungeons, get_dungeon_item_pool
|
||||
from EntranceShuffle import link_entrances
|
||||
from InvertedRegions import mark_dark_world_regions
|
||||
from ItemList import difficulties
|
||||
from Items import ItemFactory
|
||||
from Regions import create_regions
|
||||
from Rules import set_rules
|
||||
|
||||
|
||||
class TestVanilla(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.world = World(1, 'vanilla', 'noglitches', 'open', 'random', 'normal', 'normal', 'none', 'on', 'ganon', 'balanced',
|
||||
True, False, False, False, False, False, False, False, False, None,
|
||||
'none', False)
|
||||
self.world.difficulty_requirements = difficulties['normal']
|
||||
create_regions(self.world, 1)
|
||||
create_dungeons(self.world, 1)
|
||||
link_entrances(self.world, 1)
|
||||
mark_dark_world_regions(self.world)
|
||||
set_rules(self.world, 1)
|
||||
|
||||
def run_tests(self, access_pool):
|
||||
for location, access, *item_pool in access_pool:
|
||||
items = item_pool[0]
|
||||
all_except = item_pool[1] if len(item_pool) > 1 else None
|
||||
with self.subTest(location=location, access=access, items=items, all_except=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(items, 1)
|
||||
state = CollectionState(self.world)
|
||||
for item in items:
|
||||
item.advancement = True
|
||||
state.collect(item)
|
||||
|
||||
self.assertEqual(self.world.get_location(location, 1).can_reach(state), access)
|
||||
0
test/__init__.py
Normal file
0
test/__init__.py
Normal file
24
test/dungeons/TestAgahnimsTower.py
Normal file
24
test/dungeons/TestAgahnimsTower.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestAgahnimsTower(TestDungeon):
|
||||
|
||||
def testTower(self):
|
||||
self.starting_regions = ['Agahnims Tower']
|
||||
self.run_tests([
|
||||
["Castle Tower - Room 03", False, []],
|
||||
["Castle Tower - Room 03", False, [], ['Progressive Sword', 'Hammer', 'Progressive Bow', 'Fire Rod', 'Ice Rod', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Castle Tower - Room 03", True, ['Progressive Sword']],
|
||||
|
||||
["Castle Tower - Dark Maze", False, []],
|
||||
["Castle Tower - Dark Maze", False, [], ['Small Key (Agahnims Tower)']],
|
||||
["Castle Tower - Dark Maze", False, [], ['Lamp']],
|
||||
["Castle Tower - Dark Maze", False, [], ['Progressive Sword', 'Hammer', 'Progressive Bow', 'Fire Rod', 'Ice Rod', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Castle Tower - Dark Maze", True, ['Progressive Sword', 'Small Key (Agahnims Tower)', 'Lamp']],
|
||||
|
||||
["Agahnim 1", False, []],
|
||||
["Agahnim 1", False, ['Small Key (Agahnims Tower)'], ['Small Key (Agahnims Tower)']],
|
||||
["Agahnim 1", False, [], ['Progressive Sword']],
|
||||
["Agahnim 1", False, [], ['Lamp']],
|
||||
["Agahnim 1", True, ['Small Key (Agahnims Tower)', 'Small Key (Agahnims Tower)', 'Lamp', 'Progressive Sword']],
|
||||
])
|
||||
80
test/dungeons/TestDarkPalace.py
Normal file
80
test/dungeons/TestDarkPalace.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestDarkPalace(TestDungeon):
|
||||
|
||||
def testDarkPalace(self):
|
||||
self.starting_regions = ['Palace of Darkness (Entrance)']
|
||||
key = 'Small Key (Palace of Darkness)'
|
||||
self.run_tests([
|
||||
["Palace of Darkness - Shooter Room", True, []],
|
||||
|
||||
["Palace of Darkness - The Arena - Ledge", False, []],
|
||||
["Palace of Darkness - The Arena - Ledge", False, [], ['Progressive Bow']],
|
||||
["Palace of Darkness - The Arena - Ledge", True, ['Progressive Bow']],
|
||||
|
||||
["Palace of Darkness - Map Chest", False, []],
|
||||
["Palace of Darkness - Map Chest", False, [], ['Progressive Bow']],
|
||||
["Palace of Darkness - Map Chest", True, ['Progressive Bow']],
|
||||
|
||||
#Lower requirement for self-locking key
|
||||
#No lower requirement when bow/hammer is out of logic
|
||||
["Palace of Darkness - Big Key Chest", False, []],
|
||||
["Palace of Darkness - Big Key Chest", False, [key]*5, [key]],
|
||||
["Palace of Darkness - Big Key Chest", True, [key]*6],
|
||||
|
||||
["Palace of Darkness - The Arena - Bridge", False, []],
|
||||
["Palace of Darkness - The Arena - Bridge", False, [], [key, 'Progressive Bow']],
|
||||
["Palace of Darkness - The Arena - Bridge", False, [], [key, 'Hammer']],
|
||||
["Palace of Darkness - The Arena - Bridge", True, [key]],
|
||||
["Palace of Darkness - The Arena - Bridge", True, ['Progressive Bow', 'Hammer']],
|
||||
|
||||
["Palace of Darkness - Stalfos Basement", False, []],
|
||||
["Palace of Darkness - Stalfos Basement", False, [], [key, 'Progressive Bow']],
|
||||
["Palace of Darkness - Stalfos Basement", False, [], [key, 'Hammer']],
|
||||
["Palace of Darkness - Stalfos Basement", True, [key]],
|
||||
["Palace of Darkness - Stalfos Basement", True, ['Progressive Bow', 'Hammer']],
|
||||
|
||||
["Palace of Darkness - Compass Chest", False, []],
|
||||
["Palace of Darkness - Compass Chest", False, [key]*3, [key]],
|
||||
["Palace of Darkness - Compass Chest", True, [key]*4],
|
||||
|
||||
#@todo: Advanced?
|
||||
["Palace of Darkness - Dark Basement - Left", False, []],
|
||||
["Palace of Darkness - Dark Basement - Left", False, [], ['Lamp']],
|
||||
["Palace of Darkness - Dark Basement - Left", False, [key]*3, [key]],
|
||||
["Palace of Darkness - Dark Basement - Left", True, ['Lamp'] + [key]*4],
|
||||
|
||||
["Palace of Darkness - Dark Basement - Right", False, []],
|
||||
["Palace of Darkness - Dark Basement - Right", False, [], ['Lamp']],
|
||||
["Palace of Darkness - Dark Basement - Right", False, [key] * 3, [key]],
|
||||
["Palace of Darkness - Dark Basement - Right", True, ['Lamp'] + [key] * 4],
|
||||
|
||||
["Palace of Darkness - Harmless Hellway", False, []],
|
||||
["Palace of Darkness - Harmless Hellway", False, [key]*5, [key]],
|
||||
["Palace of Darkness - Harmless Hellway", True, [key]*6],
|
||||
|
||||
["Palace of Darkness - Dark Maze - Top", False, []],
|
||||
["Palace of Darkness - Dark Maze - Top", False, [], ['Lamp']],
|
||||
["Palace of Darkness - Dark Maze - Top", False, [key]*5, [key]],
|
||||
["Palace of Darkness - Dark Maze - Top", True, ['Lamp'] + [key]*6],
|
||||
|
||||
["Palace of Darkness - Dark Maze - Bottom", False, []],
|
||||
["Palace of Darkness - Dark Maze - Bottom", False, [], ['Lamp']],
|
||||
["Palace of Darkness - Dark Maze - Bottom", False, [key]*5, [key]],
|
||||
["Palace of Darkness - Dark Maze - Bottom", True, ['Lamp'] + [key]*6],
|
||||
|
||||
["Palace of Darkness - Big Chest", False, []],
|
||||
["Palace of Darkness - Big Chest", False, [], ['Lamp']],
|
||||
["Palace of Darkness - Big Chest", False, [], ['Big Key (Palace of Darkness)']],
|
||||
["Palace of Darkness - Big Chest", False, [key]*5, [key]],
|
||||
["Palace of Darkness - Big Chest", True, ['Lamp', 'Big Key (Palace of Darkness)'] + [key]*6],
|
||||
|
||||
["Palace of Darkness - Boss", False, []],
|
||||
["Palace of Darkness - Boss", False, [], ['Lamp']],
|
||||
["Palace of Darkness - Boss", False, [], ['Hammer']],
|
||||
["Palace of Darkness - Boss", False, [], ['Progressive Bow']],
|
||||
["Palace of Darkness - Boss", False, [], ['Big Key (Palace of Darkness)']],
|
||||
["Palace of Darkness - Boss", False, [key]*5, [key]],
|
||||
["Palace of Darkness - Boss", True, ['Lamp', 'Hammer', 'Progressive Bow', 'Big Key (Palace of Darkness)'] + [key]*6],
|
||||
])
|
||||
39
test/dungeons/TestDesertPalace.py
Normal file
39
test/dungeons/TestDesertPalace.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestDesertPalace(TestDungeon):
|
||||
|
||||
def testDesertPalace(self):
|
||||
self.starting_regions = ['Desert Palace North', 'Desert Palace Main (Inner)', 'Desert Palace Main (Outer)']
|
||||
self.run_tests([
|
||||
["Desert Palace - Map Chest", True, []],
|
||||
|
||||
["Desert Palace - Big Chest", False, []],
|
||||
["Desert Palace - Big Chest", False, [], ['Big Key (Desert Palace)']],
|
||||
["Desert Palace - Big Chest", True, ['Big Key (Desert Palace)']],
|
||||
|
||||
["Desert Palace - Torch", False, []],
|
||||
["Desert Palace - Torch", False, [], ['Pegasus Boots']],
|
||||
["Desert Palace - Torch", True, ['Pegasus Boots']],
|
||||
|
||||
["Desert Palace - Compass Chest", False, []],
|
||||
["Desert Palace - Compass Chest", False, [], ['Small Key (Desert Palace)']],
|
||||
["Desert Palace - Compass Chest", True, ['Small Key (Desert Palace)']],
|
||||
|
||||
#@todo: Require a real weapon for enemizer?
|
||||
["Desert Palace - Big Key Chest", False, []],
|
||||
["Desert Palace - Big Key Chest", False, [], ['Small Key (Desert Palace)']],
|
||||
["Desert Palace - Big Key Chest", True, ['Small Key (Desert Palace)']],
|
||||
|
||||
["Desert Palace - Boss", False, []],
|
||||
["Desert Palace - Boss", False, [], ['Small Key (Desert Palace)']],
|
||||
["Desert Palace - Boss", False, [], ['Big Key (Desert Palace)']],
|
||||
["Desert Palace - Boss", False, [], ['Lamp', 'Fire Rod']],
|
||||
["Desert Palace - Boss", False, [], ['Progressive Sword', 'Hammer', 'Fire Rod', 'Ice Rod', 'Progressive Bow', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Desert Palace - Boss", True, ['Small Key (Desert Palace)', 'Big Key (Desert Palace)', 'Fire Rod']],
|
||||
["Desert Palace - Boss", True, ['Small Key (Desert Palace)', 'Big Key (Desert Palace)', 'Lamp', 'Progressive Sword']],
|
||||
["Desert Palace - Boss", True, ['Small Key (Desert Palace)', 'Big Key (Desert Palace)', 'Lamp', 'Hammer']],
|
||||
["Desert Palace - Boss", True, ['Small Key (Desert Palace)', 'Big Key (Desert Palace)', 'Lamp', 'Ice Rod']],
|
||||
["Desert Palace - Boss", True, ['Small Key (Desert Palace)', 'Big Key (Desert Palace)', 'Lamp', 'Cane of Somaria']],
|
||||
["Desert Palace - Boss", True, ['Small Key (Desert Palace)', 'Big Key (Desert Palace)', 'Lamp', 'Cane of Byrna']],
|
||||
])
|
||||
49
test/dungeons/TestDungeon.py
Normal file
49
test/dungeons/TestDungeon.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import unittest
|
||||
|
||||
from BaseClasses import World, CollectionState
|
||||
from Dungeons import create_dungeons, get_dungeon_item_pool
|
||||
from EntranceShuffle import mandatory_connections, connect_simple
|
||||
from ItemList import difficulties, generate_itempool
|
||||
from Items import ItemFactory
|
||||
from Regions import create_regions
|
||||
from Rules import set_rules
|
||||
|
||||
|
||||
class TestDungeon(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.world = World(1, 'vanilla', 'noglitches', 'open', 'random', 'normal', 'normal', 'none', 'on', 'ganon', 'balanced',
|
||||
True, False, False, False, False, False, False, False, False, None,
|
||||
'none', False)
|
||||
self.starting_regions = []
|
||||
self.world.difficulty_requirements = difficulties['normal']
|
||||
create_regions(self.world, 1)
|
||||
create_dungeons(self.world, 1)
|
||||
for exitname, regionname in mandatory_connections:
|
||||
connect_simple(self.world, exitname, regionname, 1)
|
||||
connect_simple(self.world, self.world.get_entrance('Big Bomb Shop', 1), self.world.get_region('Big Bomb Shop', 1), 1)
|
||||
self.world.swamp_patch_required[1] = True
|
||||
set_rules(self.world, 1)
|
||||
generate_itempool(self.world, 1)
|
||||
self.world.itempool.extend(get_dungeon_item_pool(self.world))
|
||||
self.world.itempool.extend(ItemFactory(['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'], 1))
|
||||
|
||||
def run_tests(self, access_pool):
|
||||
for region in self.starting_regions:
|
||||
self.world.get_region(region, 1).can_reach_private = lambda _: True
|
||||
|
||||
for location, access, *item_pool in access_pool:
|
||||
items = item_pool[0]
|
||||
all_except = item_pool[1] if len(item_pool) > 1 else None
|
||||
with self.subTest(location=location, access=access, items=items, all_except=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(items, 1)
|
||||
state = CollectionState(self.world)
|
||||
for item in items:
|
||||
item.advancement = True
|
||||
state.collect(item)
|
||||
|
||||
self.assertEqual(self.world.get_location(location, 1).can_reach(state), access)
|
||||
29
test/dungeons/TestEasternPalace.py
Normal file
29
test/dungeons/TestEasternPalace.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestEasternPalace(TestDungeon):
|
||||
|
||||
def testEastern(self):
|
||||
self.starting_regions = ["Eastern Palace"]
|
||||
self.run_tests([
|
||||
["Eastern Palace - Compass Chest", True, []],
|
||||
|
||||
["Eastern Palace - Cannonball Chest", True, []],
|
||||
|
||||
["Eastern Palace - Big Chest", False, []],
|
||||
["Eastern Palace - Big Chest", False, [], ['Big Key (Eastern Palace)']],
|
||||
["Eastern Palace - Big Chest", True, ['Big Key (Eastern Palace)']],
|
||||
|
||||
["Eastern Palace - Map Chest", True, []],
|
||||
|
||||
["Eastern Palace - Big Key Chest", False, []],
|
||||
["Eastern Palace - Big Key Chest", False, [], ['Lamp']],
|
||||
["Eastern Palace - Big Key Chest", True, ['Lamp']],
|
||||
|
||||
#@todo: Advanced?
|
||||
["Eastern Palace - Boss", False, []],
|
||||
["Eastern Palace - Boss", False, [], ['Lamp']],
|
||||
["Eastern Palace - Boss", False, [], ['Progressive Bow']],
|
||||
["Eastern Palace - Boss", False, [], ['Big Key (Eastern Palace)']],
|
||||
["Eastern Palace - Boss", True, ['Lamp', 'Progressive Bow', 'Big Key (Eastern Palace)']]
|
||||
])
|
||||
144
test/dungeons/TestGanonsTower.py
Normal file
144
test/dungeons/TestGanonsTower.py
Normal file
@@ -0,0 +1,144 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestGanonsTower(TestDungeon):
|
||||
|
||||
def testGanonsTower(self):
|
||||
self.starting_regions = ['Ganons Tower (Entrance)']
|
||||
self.run_tests([
|
||||
["Ganons Tower - Bob's Torch", False, []],
|
||||
["Ganons Tower - Bob's Torch", False, [], ['Pegasus Boots']],
|
||||
["Ganons Tower - Bob's Torch", True, ['Pegasus Boots']],
|
||||
|
||||
["Ganons Tower - DMs Room - Top Left", False, []],
|
||||
["Ganons Tower - DMs Room - Top Left", False, [], ['Hammer']],
|
||||
["Ganons Tower - DMs Room - Top Left", False, [], ['Hookshot']],
|
||||
["Ganons Tower - DMs Room - Top Left", True, ['Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - DMs Room - Top Right", False, []],
|
||||
["Ganons Tower - DMs Room - Top Right", False, [], ['Hammer']],
|
||||
["Ganons Tower - DMs Room - Top Right", False, [], ['Hookshot']],
|
||||
["Ganons Tower - DMs Room - Top Right", True, ['Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - DMs Room - Bottom Left", False, []],
|
||||
["Ganons Tower - DMs Room - Bottom Left", False, [], ['Hammer']],
|
||||
["Ganons Tower - DMs Room - Bottom Left", False, [], ['Hookshot']],
|
||||
["Ganons Tower - DMs Room - Bottom Left", True, ['Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - DMs Room - Bottom Right", False, []],
|
||||
["Ganons Tower - DMs Room - Bottom Right", False, [], ['Hammer']],
|
||||
["Ganons Tower - DMs Room - Bottom Right", False, [], ['Hookshot']],
|
||||
["Ganons Tower - DMs Room - Bottom Right", True, ['Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Randomizer Room - Top Left", False, []],
|
||||
["Ganons Tower - Randomizer Room - Top Left", False, [], ['Hammer']],
|
||||
["Ganons Tower - Randomizer Room - Top Left", False, [], ['Hookshot']],
|
||||
["Ganons Tower - Randomizer Room - Top Left", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Randomizer Room - Top Right", False, []],
|
||||
["Ganons Tower - Randomizer Room - Top Right", False, [], ['Hammer']],
|
||||
["Ganons Tower - Randomizer Room - Top Right", False, [], ['Hookshot']],
|
||||
["Ganons Tower - Randomizer Room - Top Right", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Randomizer Room - Bottom Left", False, []],
|
||||
["Ganons Tower - Randomizer Room - Bottom Left", False, [], ['Hammer']],
|
||||
["Ganons Tower - Randomizer Room - Bottom Left", False, [], ['Hookshot']],
|
||||
["Ganons Tower - Randomizer Room - Bottom Left", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Randomizer Room - Bottom Right", False, []],
|
||||
["Ganons Tower - Randomizer Room - Bottom Right", False, [], ['Hammer']],
|
||||
["Ganons Tower - Randomizer Room - Bottom Right", False, [], ['Hookshot']],
|
||||
["Ganons Tower - Randomizer Room - Bottom Right", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Firesnake Room", False, []],
|
||||
["Ganons Tower - Firesnake Room", False, [], ['Hammer']],
|
||||
["Ganons Tower - Firesnake Room", False, [], ['Hookshot']],
|
||||
["Ganons Tower - Firesnake Room", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Map Chest", False, []],
|
||||
["Ganons Tower - Map Chest", False, [], ['Hammer']],
|
||||
["Ganons Tower - Map Chest", False, [], ['Hookshot', 'Pegasus Boots']],
|
||||
["Ganons Tower - Map Chest", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
["Ganons Tower - Map Chest", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hammer', 'Pegasus Boots']],
|
||||
|
||||
["Ganons Tower - Big Chest", False, []],
|
||||
["Ganons Tower - Big Chest", False, [], ['Big Key (Ganons Tower)']],
|
||||
["Ganons Tower - Big Chest", True, ['Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Cane of Somaria', 'Fire Rod']],
|
||||
["Ganons Tower - Big Chest", True, ['Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Hope Room - Left", True, []],
|
||||
|
||||
["Ganons Tower - Hope Room - Right", True, []],
|
||||
|
||||
["Ganons Tower - Bob's Chest", False, []],
|
||||
["Ganons Tower - Bob's Chest", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Cane of Somaria', 'Fire Rod']],
|
||||
["Ganons Tower - Bob's Chest", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Tile Room", False, []],
|
||||
["Ganons Tower - Tile Room", False, [], ['Cane of Somaria']],
|
||||
["Ganons Tower - Tile Room", True, ['Cane of Somaria']],
|
||||
|
||||
["Ganons Tower - Compass Room - Top Left", False, []],
|
||||
["Ganons Tower - Compass Room - Top Left", False, [], ['Cane of Somaria']],
|
||||
["Ganons Tower - Compass Room - Top Left", False, [], ['Fire Rod']],
|
||||
["Ganons Tower - Compass Room - Top Left", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Cane of Somaria']],
|
||||
|
||||
["Ganons Tower - Compass Room - Top Right", False, []],
|
||||
["Ganons Tower - Compass Room - Top Right", False, [], ['Cane of Somaria']],
|
||||
["Ganons Tower - Compass Room - Top Right", False, [], ['Fire Rod']],
|
||||
["Ganons Tower - Compass Room - Top Right", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Cane of Somaria']],
|
||||
|
||||
["Ganons Tower - Compass Room - Bottom Left", False, []],
|
||||
["Ganons Tower - Compass Room - Bottom Left", False, [], ['Cane of Somaria']],
|
||||
["Ganons Tower - Compass Room - Bottom Left", False, [], ['Fire Rod']],
|
||||
["Ganons Tower - Compass Room - Bottom Left", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Cane of Somaria']],
|
||||
|
||||
["Ganons Tower - Compass Room - Bottom Right", False, []],
|
||||
["Ganons Tower - Compass Room - Bottom Right", False, [], ['Cane of Somaria']],
|
||||
["Ganons Tower - Compass Room - Bottom Right", False, [], ['Fire Rod']],
|
||||
["Ganons Tower - Compass Room - Bottom Right", True, ['Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Cane of Somaria']],
|
||||
|
||||
["Ganons Tower - Big Key Chest", False, []],
|
||||
["Ganons Tower - Big Key Chest", True, ['Progressive Bow', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Cane of Somaria', 'Fire Rod']],
|
||||
["Ganons Tower - Big Key Chest", True, ['Progressive Bow', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Big Key Room - Left", False, []],
|
||||
["Ganons Tower - Big Key Room - Left", True, ['Progressive Bow', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Cane of Somaria', 'Fire Rod']],
|
||||
["Ganons Tower - Big Key Room - Left", True, ['Progressive Bow', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Big Key Room - Right", False, []],
|
||||
["Ganons Tower - Big Key Room - Right", True, ['Progressive Bow', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Cane of Somaria', 'Fire Rod']],
|
||||
["Ganons Tower - Big Key Room - Right", True, ['Progressive Bow', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Hookshot', 'Hammer']],
|
||||
|
||||
["Ganons Tower - Mini Helmasaur Room - Left", False, []],
|
||||
["Ganons Tower - Mini Helmasaur Room - Left", False, [], ['Progressive Bow']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Left", False, [], ['Big Key (Ganons Tower)']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Left", False, [], ['Lamp', 'Fire Rod']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Left", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Left", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']],
|
||||
|
||||
["Ganons Tower - Mini Helmasaur Room - Right", False, []],
|
||||
["Ganons Tower - Mini Helmasaur Room - Right", False, [], ['Progressive Bow']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Right", False, [], ['Big Key (Ganons Tower)']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Right", False, [], ['Lamp', 'Fire Rod']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Right", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']],
|
||||
["Ganons Tower - Mini Helmasaur Room - Right", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']],
|
||||
|
||||
["Ganons Tower - Pre-Moldorm Chest", False, []],
|
||||
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Progressive Bow']],
|
||||
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Big Key (Ganons Tower)']],
|
||||
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Lamp', 'Fire Rod']],
|
||||
["Ganons Tower - Pre-Moldorm Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']],
|
||||
["Ganons Tower - Pre-Moldorm Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']],
|
||||
|
||||
["Ganons Tower - Validation Chest", False, []],
|
||||
["Ganons Tower - Validation Chest", False, [], ['Hookshot']],
|
||||
["Ganons Tower - Validation Chest", False, [], ['Progressive Bow']],
|
||||
["Ganons Tower - Validation Chest", False, [], ['Big Key (Ganons Tower)']],
|
||||
["Ganons Tower - Validation Chest", False, [], ['Lamp', 'Fire Rod']],
|
||||
["Ganons Tower - Validation Chest", False, [], ['Progressive Sword', 'Hammer']],
|
||||
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Progressive Sword']],
|
||||
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Progressive Sword']],
|
||||
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Hammer']],
|
||||
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Hammer']],
|
||||
])
|
||||
79
test/dungeons/TestIcePalace.py
Normal file
79
test/dungeons/TestIcePalace.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestIcePalace(TestDungeon):
|
||||
|
||||
def testIcePalace(self):
|
||||
self.starting_regions = ['Ice Palace (Entrance)']
|
||||
self.run_tests([
|
||||
["Ice Palace - Big Key Chest", False, []],
|
||||
["Ice Palace - Big Key Chest", False, [], ['Hammer']],
|
||||
["Ice Palace - Big Key Chest", False, [], ['Progressive Glove']],
|
||||
["Ice Palace - Big Key Chest", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Big Key Chest", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Big Key Chest", True, ['Progressive Glove', 'Fire Rod', 'Hammer', 'Hookshot', 'Small Key (Ice Palace)']],
|
||||
["Ice Palace - Big Key Chest", True, ['Progressive Glove', 'Bombos', 'Progressive Sword', 'Hammer', 'Hookshot', 'Small Key (Ice Palace)']],
|
||||
#@todo: Change from item randomizer - Right side key door is only in logic if big key is in there
|
||||
#["Ice Palace - Big Key Chest", True, ['Progressive Glove', 'Cane of Byrna', 'Fire Rod', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Big Key Chest", True, ['Progressive Glove', 'Cane of Byrna', 'Bombos', 'Progressive Sword', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Big Key Chest", True, ['Progressive Glove', 'Cape', 'Fire Rod', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Big Key Chest", True, ['Progressive Glove', 'Cape', 'Bombos', 'Progressive Sword', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
|
||||
["Ice Palace - Compass Chest", False, []],
|
||||
["Ice Palace - Compass Chest", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Compass Chest", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Compass Chest", True, ['Fire Rod']],
|
||||
["Ice Palace - Compass Chest", True, ['Bombos', 'Progressive Sword']],
|
||||
|
||||
["Ice Palace - Map Chest", False, []],
|
||||
["Ice Palace - Map Chest", False, [], ['Hammer']],
|
||||
["Ice Palace - Map Chest", False, [], ['Progressive Glove']],
|
||||
["Ice Palace - Map Chest", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Map Chest", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Map Chest", True, ['Progressive Glove', 'Fire Rod', 'Hammer', 'Hookshot', 'Small Key (Ice Palace)']],
|
||||
["Ice Palace - Map Chest", True, ['Progressive Glove', 'Bombos', 'Progressive Sword', 'Hammer', 'Hookshot', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Map Chest", True, ['Progressive Glove', 'Cane of Byrna', 'Fire Rod', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Map Chest", True, ['Progressive Glove', 'Cane of Byrna', 'Bombos', 'Progressive Sword', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Map Chest", True, ['Progressive Glove', 'Cape', 'Fire Rod', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Map Chest", True, ['Progressive Glove', 'Cape', 'Bombos', 'Progressive Sword', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
|
||||
["Ice Palace - Spike Room", False, []],
|
||||
["Ice Palace - Spike Room", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Spike Room", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Spike Room", True, ['Fire Rod', 'Hookshot', 'Small Key (Ice Palace)']],
|
||||
["Ice Palace - Spike Room", True, ['Bombos', 'Progressive Sword', 'Hookshot', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Spike Room", True, ['Cape', 'Fire Rod', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Spike Room", True, ['Cape', 'Bombos', 'Progressive Sword', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Spike Room", True, ['Cane of Byrna', 'Fire Rod', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
#["Ice Palace - Spike Room", True, ['Cane of Byrna', 'Bombos', 'Progressive Sword', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
|
||||
["Ice Palace - Freezor Chest", False, []],
|
||||
["Ice Palace - Freezor Chest", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Freezor Chest", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Freezor Chest", True, ['Fire Rod']],
|
||||
["Ice Palace - Freezor Chest", True, ['Bombos', 'Progressive Sword']],
|
||||
|
||||
["Ice Palace - Iced T Room", False, []],
|
||||
["Ice Palace - Iced T Room", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Iced T Room", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Iced T Room", True, ['Fire Rod']],
|
||||
["Ice Palace - Iced T Room", True, ['Bombos', 'Progressive Sword']],
|
||||
|
||||
["Ice Palace - Big Chest", False, []],
|
||||
["Ice Palace - Big Chest", False, [], ['Big Key (Ice Palace)']],
|
||||
["Ice Palace - Big Chest", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Big Chest", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Big Chest", True, ['Big Key (Ice Palace)', 'Fire Rod']],
|
||||
["Ice Palace - Big Chest", True, ['Big Key (Ice Palace)', 'Bombos', 'Progressive Sword']],
|
||||
|
||||
["Ice Palace - Boss", False, []],
|
||||
["Ice Palace - Boss", False, [], ['Hammer']],
|
||||
["Ice Palace - Boss", False, [], ['Progressive Glove']],
|
||||
["Ice Palace - Boss", False, [], ['Big Key (Ice Palace)']],
|
||||
["Ice Palace - Boss", False, [], ['Fire Rod', 'Bombos']],
|
||||
["Ice Palace - Boss", False, [], ['Fire Rod', 'Progressive Sword']],
|
||||
["Ice Palace - Boss", True, ['Progressive Glove', 'Big Key (Ice Palace)', 'Fire Rod', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
["Ice Palace - Boss", True, ['Progressive Glove', 'Big Key (Ice Palace)', 'Fire Rod', 'Hammer', 'Cane of Somaria', 'Small Key (Ice Palace)']],
|
||||
["Ice Palace - Boss", True, ['Progressive Glove', 'Big Key (Ice Palace)', 'Bombos', 'Progressive Sword', 'Hammer', 'Small Key (Ice Palace)', 'Small Key (Ice Palace)']],
|
||||
["Ice Palace - Boss", True, ['Progressive Glove', 'Big Key (Ice Palace)', 'Bombos', 'Progressive Sword', 'Hammer', 'Cane of Somaria', 'Small Key (Ice Palace)']],
|
||||
])
|
||||
84
test/dungeons/TestMiseryMire.py
Normal file
84
test/dungeons/TestMiseryMire.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestMiseryMire(TestDungeon):
|
||||
|
||||
def testMiseryMire(self):
|
||||
self.starting_regions = ['Misery Mire (Entrance)']
|
||||
self.run_tests([
|
||||
["Misery Mire - Bridge Chest", False, []],
|
||||
["Misery Mire - Bridge Chest", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Bridge Chest", False, [], ['Progressive Sword', 'Hammer', 'Fire Rod', 'Cane of Somaria', 'Progressive Bow', 'Ice Rod']], #Ice Rod works!
|
||||
["Misery Mire - Bridge Chest", True, ['Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Bridge Chest", True, ['Progressive Sword', 'Hookshot']],
|
||||
["Misery Mire - Bridge Chest", True, ['Hammer', 'Pegasus Boots']],
|
||||
["Misery Mire - Bridge Chest", True, ['Hammer', 'Hookshot']],
|
||||
["Misery Mire - Bridge Chest", True, ['Fire Rod', 'Pegasus Boots']],
|
||||
["Misery Mire - Bridge Chest", True, ['Fire Rod', 'Hookshot']],
|
||||
["Misery Mire - Bridge Chest", True, ['Cane of Somaria', 'Pegasus Boots']],
|
||||
["Misery Mire - Bridge Chest", True, ['Cane of Somaria', 'Hookshot']],
|
||||
["Misery Mire - Bridge Chest", True, ['Progressive Bow', 'Pegasus Boots']],
|
||||
["Misery Mire - Bridge Chest", True, ['Progressive Bow', 'Hookshot']],
|
||||
["Misery Mire - Bridge Chest", True, ['Ice Rod', 'Pegasus Boots']],
|
||||
["Misery Mire - Bridge Chest", True, ['Ice Rod', 'Hookshot']],
|
||||
|
||||
["Misery Mire - Big Chest", False, []],
|
||||
["Misery Mire - Big Chest", False, [], ['Big Key (Misery Mire)']],
|
||||
["Misery Mire - Big Chest", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Big Chest", False, [], ['Progressive Sword', 'Hammer', 'Fire Rod', 'Cane of Somaria', 'Progressive Bow', 'Ice Rod']],
|
||||
["Misery Mire - Big Chest", True, ['Big Key (Misery Mire)', 'Pegasus Boots', 'Progressive Sword']],
|
||||
["Misery Mire - Big Chest", True, ['Big Key (Misery Mire)', 'Hookshot', 'Progressive Sword']],
|
||||
|
||||
["Misery Mire - Main Lobby", False, []],
|
||||
["Misery Mire - Main Lobby", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Main Lobby", False, [], ['Small Key (Misery Mire)', 'Big Key (Misery Mire)']],
|
||||
["Misery Mire - Main Lobby", True, ['Small Key (Misery Mire)', 'Hookshot', 'Progressive Sword']],
|
||||
["Misery Mire - Main Lobby", True, ['Small Key (Misery Mire)', 'Pegasus Boots', 'Progressive Sword']],
|
||||
["Misery Mire - Main Lobby", True, ['Big Key (Misery Mire)', 'Hookshot', 'Progressive Sword']],
|
||||
["Misery Mire - Main Lobby", True, ['Big Key (Misery Mire)', 'Pegasus Boots', 'Progressive Sword']],
|
||||
|
||||
["Misery Mire - Big Key Chest", False, []],
|
||||
["Misery Mire - Big Key Chest", False, [], ['Fire Rod', 'Lamp']],
|
||||
["Misery Mire - Big Key Chest", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Big Key Chest", False, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)'], ['Small Key (Misery Mire)']],
|
||||
["Misery Mire - Big Key Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Lamp', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Big Key Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Lamp', 'Progressive Sword', 'Hookshot']],
|
||||
["Misery Mire - Big Key Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Fire Rod', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Big Key Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Fire Rod', 'Progressive Sword', 'Hookshot']],
|
||||
|
||||
["Misery Mire - Compass Chest", False, []],
|
||||
["Misery Mire - Compass Chest", False, [], ['Fire Rod', 'Lamp']],
|
||||
["Misery Mire - Compass Chest", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Compass Chest", False, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)'], ['Small Key (Misery Mire)']],
|
||||
["Misery Mire - Compass Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Lamp', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Compass Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Lamp', 'Progressive Sword', 'Hookshot']],
|
||||
["Misery Mire - Compass Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Fire Rod', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Compass Chest", True, ['Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Small Key (Misery Mire)', 'Fire Rod', 'Progressive Sword', 'Hookshot']],
|
||||
|
||||
["Misery Mire - Map Chest", False, []],
|
||||
["Misery Mire - Map Chest", False, [], ['Small Key (Misery Mire)', 'Big Key (Misery Mire)']],
|
||||
["Misery Mire - Map Chest", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Map Chest", True, ['Small Key (Misery Mire)', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Map Chest", True, ['Small Key (Misery Mire)', 'Progressive Sword', 'Hookshot']],
|
||||
["Misery Mire - Map Chest", True, ['Big Key (Misery Mire)', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Map Chest", True, ['Big Key (Misery Mire)', 'Progressive Sword', 'Hookshot']],
|
||||
|
||||
["Misery Mire - Spike Chest", False, []],
|
||||
["Misery Mire - Spike Chest", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Spike Chest", True, ['Progressive Sword', 'Pegasus Boots', 'Cape']],
|
||||
["Misery Mire - Spike Chest", True, ['Progressive Sword', 'Hookshot', 'Cape']],
|
||||
["Misery Mire - Spike Chest", True, ['Progressive Sword', 'Pegasus Boots', 'Cane of Byrna']],
|
||||
["Misery Mire - Spike Chest", True, ['Progressive Sword', 'Hookshot', 'Cane of Byrna']],
|
||||
["Misery Mire - Spike Chest", True, ['Progressive Sword', 'Pegasus Boots', 'Boss Heart Container']],
|
||||
["Misery Mire - Spike Chest", True, ['Progressive Sword', 'Hookshot', 'Boss Heart Container']],
|
||||
|
||||
["Misery Mire - Boss", False, []],
|
||||
["Misery Mire - Boss", False, [], ['Lamp']],
|
||||
["Misery Mire - Boss", False, [], ['Cane of Somaria']],
|
||||
["Misery Mire - Boss", False, [], ['Progressive Sword', 'Hammer', 'Progressive Bow']],
|
||||
["Misery Mire - Boss", False, [], ['Big Key (Misery Mire)']],
|
||||
["Misery Mire - Boss", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Misery Mire - Boss", True, ['Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Progressive Sword', 'Pegasus Boots']],
|
||||
["Misery Mire - Boss", True, ['Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Hammer', 'Pegasus Boots']],
|
||||
["Misery Mire - Boss", True, ['Big Key (Misery Mire)', 'Lamp', 'Cane of Somaria', 'Progressive Bow', 'Pegasus Boots']],
|
||||
])
|
||||
96
test/dungeons/TestSkullWoods.py
Normal file
96
test/dungeons/TestSkullWoods.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestSkullWoods(TestDungeon):
|
||||
|
||||
def testSkullWoodsFrontAllEntrances(self):
|
||||
self.starting_regions = ['Skull Woods First Section', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)']
|
||||
self.run_tests([
|
||||
["Skull Woods - Big Chest", False, []],
|
||||
["Skull Woods - Big Chest", False, [], ['Big Key (Skull Woods)']],
|
||||
["Skull Woods - Big Chest", True, ['Big Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Compass Chest", True, []],
|
||||
|
||||
["Skull Woods - Map Chest", True, []],
|
||||
|
||||
["Skull Woods - Pot Prison", True, []],
|
||||
|
||||
["Skull Woods - Pinball Room", True, []]
|
||||
])
|
||||
|
||||
def testSkullWoodsFrontOnly(self):
|
||||
self.starting_regions = ['Skull Woods First Section']
|
||||
self.run_tests([
|
||||
["Skull Woods - Big Chest", False, []],
|
||||
["Skull Woods - Big Chest", False, [], ['Never in logic']],
|
||||
|
||||
["Skull Woods - Compass Chest", False, []],
|
||||
["Skull Woods - Compass Chest", False, ['Small Key (Skull Woods)'], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Compass Chest", True, ['Small Key (Skull Woods)', 'Small Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Map Chest", True, []],
|
||||
|
||||
["Skull Woods - Pot Prison", False, []],
|
||||
["Skull Woods - Pot Prison", False, ['Small Key (Skull Woods)'], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Pot Prison", True, ['Small Key (Skull Woods)', 'Small Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Pinball Room", False, []],
|
||||
["Skull Woods - Pinball Room", False, [], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Pinball Room", True, ['Small Key (Skull Woods)']]
|
||||
])
|
||||
|
||||
def testSkullWoodsLeftOnly(self):
|
||||
self.starting_regions = ['Skull Woods First Section (Left)']
|
||||
self.run_tests([
|
||||
["Skull Woods - Big Chest", False, []],
|
||||
["Skull Woods - Big Chest", False, [], ['Never in logic']],
|
||||
|
||||
["Skull Woods - Compass Chest", True, []],
|
||||
|
||||
["Skull Woods - Map Chest", False, []],
|
||||
["Skull Woods - Map Chest", False, [], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Map Chest", True, ['Small Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Pot Prison", True, []],
|
||||
|
||||
["Skull Woods - Pinball Room", True, []]
|
||||
])
|
||||
|
||||
def testSkullWoodsBackOnly(self):
|
||||
self.starting_regions = ['Skull Woods First Section (Top)']
|
||||
self.run_tests([
|
||||
["Skull Woods - Big Chest", False, []],
|
||||
["Skull Woods - Big Chest", False, [], ['Big Key (Skull Woods)']],
|
||||
["Skull Woods - Big Chest", True, ['Big Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Compass Chest", False, []],
|
||||
["Skull Woods - Compass Chest", False, ['Small Key (Skull Woods)'], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Compass Chest", True, ['Small Key (Skull Woods)', 'Small Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Map Chest", True, []],
|
||||
|
||||
["Skull Woods - Pot Prison", False, []],
|
||||
["Skull Woods - Pot Prison", False, ['Small Key (Skull Woods)'], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Pot Prison", True, ['Small Key (Skull Woods)', 'Small Key (Skull Woods)']],
|
||||
|
||||
["Skull Woods - Pinball Room", False, []],
|
||||
["Skull Woods - Pinball Room", False, [], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Pinball Room", True, ['Small Key (Skull Woods)']]
|
||||
])
|
||||
|
||||
def testSkullWoodsMiddle(self):
|
||||
self.starting_regions = ['Skull Woods Second Section']
|
||||
self.run_tests([["Skull Woods - Big Key Chest", True, []]])
|
||||
|
||||
def testSkullWoodsBack(self):
|
||||
self.starting_regions = ['Skull Woods Final Section (Entrance)']
|
||||
self.run_tests([
|
||||
["Skull Woods - Bridge Room", True, []],
|
||||
|
||||
["Skull Woods - Boss", False, []],
|
||||
["Skull Woods - Boss", False, [], ['Fire Rod']],
|
||||
["Skull Woods - Boss", False, [], ['Progressive Sword']],
|
||||
["Skull Woods - Boss", False, ['Small Key (Skull Woods)', 'Small Key (Skull Woods)'], ['Small Key (Skull Woods)']],
|
||||
["Skull Woods - Boss", True, ['Small Key (Skull Woods)', 'Small Key (Skull Woods)', 'Small Key (Skull Woods)', 'Fire Rod', 'Progressive Sword']],
|
||||
])
|
||||
80
test/dungeons/TestSwampPalace.py
Normal file
80
test/dungeons/TestSwampPalace.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestSwampPalace(TestDungeon):
|
||||
|
||||
def testSwampPalace(self):
|
||||
self.starting_regions = ['Swamp Palace (Entrance)']
|
||||
self.run_tests([
|
||||
["Swamp Palace - Entrance", False, []],
|
||||
["Swamp Palace - Entrance", False, [], ['Flippers']],
|
||||
["Swamp Palace - Entrance", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Entrance", True, ['Open Floodgate', 'Flippers']],
|
||||
|
||||
["Swamp Palace - Big Chest", False, []],
|
||||
["Swamp Palace - Big Chest", False, [], ['Flippers']],
|
||||
["Swamp Palace - Big Chest", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Big Chest", False, [], ['Hammer']],
|
||||
["Swamp Palace - Big Chest", False, [], ['Big Key (Swamp Palace)']],
|
||||
["Swamp Palace - Big Chest", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Big Chest", True, ['Open Floodgate', 'Big Key (Swamp Palace)', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']],
|
||||
|
||||
["Swamp Palace - Big Key Chest", False, []],
|
||||
["Swamp Palace - Big Key Chest", False, [], ['Flippers']],
|
||||
["Swamp Palace - Big Key Chest", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Big Key Chest", False, [], ['Hammer']],
|
||||
["Swamp Palace - Big Key Chest", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Big Key Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']],
|
||||
|
||||
["Swamp Palace - Map Chest", False, []],
|
||||
["Swamp Palace - Map Chest", False, [], ['Flippers']],
|
||||
["Swamp Palace - Map Chest", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Map Chest", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Map Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers']],
|
||||
|
||||
["Swamp Palace - West Chest", False, []],
|
||||
["Swamp Palace - West Chest", False, [], ['Flippers']],
|
||||
["Swamp Palace - West Chest", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - West Chest", False, [], ['Hammer']],
|
||||
["Swamp Palace - West Chest", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - West Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']],
|
||||
|
||||
["Swamp Palace - Compass Chest", False, []],
|
||||
["Swamp Palace - Compass Chest", False, [], ['Flippers']],
|
||||
["Swamp Palace - Compass Chest", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Compass Chest", False, [], ['Hammer']],
|
||||
["Swamp Palace - Compass Chest", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Compass Chest", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer']],
|
||||
|
||||
["Swamp Palace - Flooded Room - Left", False, []],
|
||||
["Swamp Palace - Flooded Room - Left", False, [], ['Flippers']],
|
||||
["Swamp Palace - Flooded Room - Left", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Flooded Room - Left", False, [], ['Hammer']],
|
||||
["Swamp Palace - Flooded Room - Left", False, [], ['Hookshot']],
|
||||
["Swamp Palace - Flooded Room - Left", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Flooded Room - Left", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer', 'Hookshot']],
|
||||
|
||||
["Swamp Palace - Flooded Room - Right", False, []],
|
||||
["Swamp Palace - Flooded Room - Right", False, [], ['Flippers']],
|
||||
["Swamp Palace - Flooded Room - Right", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Flooded Room - Right", False, [], ['Hammer']],
|
||||
["Swamp Palace - Flooded Room - Right", False, [], ['Hookshot']],
|
||||
["Swamp Palace - Flooded Room - Right", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Flooded Room - Right", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer', 'Hookshot']],
|
||||
|
||||
["Swamp Palace - Waterfall Room", False, []],
|
||||
["Swamp Palace - Waterfall Room", False, [], ['Flippers']],
|
||||
["Swamp Palace - Waterfall Room", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Waterfall Room", False, [], ['Hammer']],
|
||||
["Swamp Palace - Waterfall Room", False, [], ['Hookshot']],
|
||||
["Swamp Palace - Waterfall Room", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Waterfall Room", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer', 'Hookshot']],
|
||||
|
||||
["Swamp Palace - Boss", False, []],
|
||||
["Swamp Palace - Boss", False, [], ['Flippers']],
|
||||
["Swamp Palace - Boss", False, [], ['Open Floodgate']],
|
||||
["Swamp Palace - Boss", False, [], ['Hammer']],
|
||||
["Swamp Palace - Boss", False, [], ['Hookshot']],
|
||||
["Swamp Palace - Boss", False, [], ['Small Key (Swamp Palace)']],
|
||||
["Swamp Palace - Boss", True, ['Open Floodgate', 'Small Key (Swamp Palace)', 'Flippers', 'Hammer', 'Hookshot']],
|
||||
])
|
||||
40
test/dungeons/TestThievesTown.py
Normal file
40
test/dungeons/TestThievesTown.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestThievesTown(TestDungeon):
|
||||
|
||||
def testThievesTown(self):
|
||||
self.starting_regions = ['Thieves Town (Entrance)']
|
||||
self.run_tests([
|
||||
["Thieves' Town - Attic", False, []],
|
||||
["Thieves' Town - Attic", False, [], ['Big Key (Thieves Town)']],
|
||||
["Thieves' Town - Attic", False, [], ['Small Key (Thieves Town)']],
|
||||
["Thieves' Town - Attic", True, ['Big Key (Thieves Town)', 'Small Key (Thieves Town)']],
|
||||
|
||||
["Thieves' Town - Big Key Chest", True, []],
|
||||
|
||||
["Thieves' Town - Map Chest", True, []],
|
||||
|
||||
["Thieves' Town - Compass Chest", True, []],
|
||||
|
||||
["Thieves' Town - Ambush Chest", True, []],
|
||||
|
||||
["Thieves' Town - Big Chest", False, []],
|
||||
["Thieves' Town - Big Chest", False, [], ['Big Key (Thieves Town)']],
|
||||
["Thieves' Town - Big Chest", False, [], ['Small Key (Thieves Town)']],
|
||||
["Thieves' Town - Big Chest", False, [], ['Hammer']],
|
||||
["Thieves' Town - Big Chest", True, ['Hammer', 'Small Key (Thieves Town)', 'Big Key (Thieves Town)']],
|
||||
|
||||
["Thieves' Town - Blind's Cell", False, []],
|
||||
["Thieves' Town - Blind's Cell", False, [], ['Big Key (Thieves Town)']],
|
||||
["Thieves' Town - Blind's Cell", True, ['Big Key (Thieves Town)']],
|
||||
|
||||
["Thieves' Town - Boss", False, []],
|
||||
["Thieves' Town - Boss", False, [], ['Big Key (Thieves Town)']],
|
||||
["Thieves' Town - Boss", False, [], ['Small Key (Thieves Town)']],
|
||||
["Thieves' Town - Boss", False, [], ['Hammer', 'Progressive Sword', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Thieves' Town - Boss", True, ['Small Key (Thieves Town)', 'Big Key (Thieves Town)', 'Hammer']],
|
||||
["Thieves' Town - Boss", True, ['Small Key (Thieves Town)', 'Big Key (Thieves Town)', 'Progressive Sword']],
|
||||
["Thieves' Town - Boss", True, ['Small Key (Thieves Town)', 'Big Key (Thieves Town)', 'Cane of Somaria']],
|
||||
["Thieves' Town - Boss", True, ['Small Key (Thieves Town)', 'Big Key (Thieves Town)', 'Cane of Byrna']],
|
||||
])
|
||||
32
test/dungeons/TestTowerOfHera.py
Normal file
32
test/dungeons/TestTowerOfHera.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from test.dungeons.TestDungeon import TestDungeon
|
||||
|
||||
|
||||
class TestTowerOfHera(TestDungeon):
|
||||
|
||||
def testTowerOfHera(self):
|
||||
self.starting_regions = ['Tower of Hera (Bottom)']
|
||||
self.run_tests([
|
||||
["Tower of Hera - Big Key Chest", False, []],
|
||||
["Tower of Hera - Big Key Chest", False, [], ['Small Key (Tower of Hera)']],
|
||||
["Tower of Hera - Big Key Chest", False, [], ['Lamp', 'Fire Rod']],
|
||||
["Tower of Hera - Big Key Chest", True, ['Small Key (Tower of Hera)', 'Lamp']],
|
||||
["Tower of Hera - Big Key Chest", True, ['Small Key (Tower of Hera)', 'Fire Rod']],
|
||||
|
||||
["Tower of Hera - Basement Cage", True, []],
|
||||
|
||||
["Tower of Hera - Map Chest", True, []],
|
||||
|
||||
["Tower of Hera - Compass Chest", False, []],
|
||||
["Tower of Hera - Compass Chest", False, [], ['Big Key (Tower of Hera)']],
|
||||
["Tower of Hera - Compass Chest", True, ['Big Key (Tower of Hera)']],
|
||||
|
||||
["Tower of Hera - Big Chest", False, []],
|
||||
["Tower of Hera - Big Chest", False, [], ['Big Key (Tower of Hera)']],
|
||||
["Tower of Hera - Big Chest", True, ['Big Key (Tower of Hera)']],
|
||||
|
||||
["Tower of Hera - Boss", False, []],
|
||||
["Tower of Hera - Boss", False, [], ['Big Key (Tower of Hera)']],
|
||||
["Tower of Hera - Boss", False, [], ['Progressive Sword', 'Hammer']],
|
||||
["Tower of Hera - Boss", True, ['Progressive Sword', 'Big Key (Tower of Hera)']],
|
||||
["Tower of Hera - Boss", True, ['Hammer', 'Big Key (Tower of Hera)']],
|
||||
])
|
||||
0
test/dungeons/__init__.py
Normal file
0
test/dungeons/__init__.py
Normal file
28
test/inverted/TestInverted.py
Normal file
28
test/inverted/TestInverted.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from BaseClasses import World
|
||||
from Dungeons import create_dungeons, get_dungeon_item_pool
|
||||
from EntranceShuffle import link_inverted_entrances
|
||||
from InvertedRegions import create_inverted_regions
|
||||
from ItemList import generate_itempool, difficulties
|
||||
from Items import ItemFactory
|
||||
from Regions import mark_light_world_regions
|
||||
from Rules import set_rules
|
||||
from test.TestVanilla import TestVanilla
|
||||
|
||||
|
||||
class TestInverted(TestVanilla):
|
||||
def setUp(self):
|
||||
self.world = World(1, 'vanilla', 'noglitches', 'inverted', 'random', 'normal', 'normal', 'none', 'on', 'ganon', 'balanced',
|
||||
True, False, False, False, False, False, False, False, False, None,
|
||||
'none', False)
|
||||
self.world.difficulty_requirements = difficulties['normal']
|
||||
create_inverted_regions(self.world, 1)
|
||||
create_dungeons(self.world, 1)
|
||||
link_inverted_entrances(self.world, 1)
|
||||
generate_itempool(self.world, 1)
|
||||
self.world.required_medallions[1] = ['Ether', 'Quake']
|
||||
self.world.itempool.extend(get_dungeon_item_pool(self.world))
|
||||
self.world.itempool.extend(ItemFactory(['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Beat Agahnim 2', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'], 1))
|
||||
self.world.get_location('Agahnim 1', 1).item = None
|
||||
self.world.get_location('Agahnim 2', 1).item = None
|
||||
mark_light_world_regions(self.world)
|
||||
set_rules(self.world, 1)
|
||||
47
test/inverted/TestInvertedBombRules.py
Normal file
47
test/inverted/TestInvertedBombRules.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import unittest
|
||||
|
||||
from BaseClasses import World
|
||||
from Dungeons import create_dungeons
|
||||
from EntranceShuffle import connect_entrance, Inverted_LW_Entrances, Inverted_LW_Dungeon_Entrances, Inverted_LW_Single_Cave_Doors, Inverted_Old_Man_Entrances, Inverted_DW_Entrances, Inverted_DW_Dungeon_Entrances, Inverted_DW_Single_Cave_Doors, \
|
||||
Inverted_LW_Entrances_Must_Exit, Inverted_LW_Dungeon_Entrances_Must_Exit, Inverted_Bomb_Shop_Multi_Cave_Doors, Inverted_Bomb_Shop_Single_Cave_Doors, Inverted_Blacksmith_Single_Cave_Doors, Inverted_Blacksmith_Multi_Cave_Doors
|
||||
from InvertedRegions import create_inverted_regions
|
||||
from ItemList import difficulties
|
||||
from Rules import set_inverted_big_bomb_rules
|
||||
|
||||
|
||||
class TestInvertedBombRules(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.world = World(1, 'vanilla', 'noglitches', 'inverted', 'random', 'normal', 'normal', 'none', 'on', 'ganon', 'balanced',
|
||||
True, False, False, False, False, False, False, False, False, None,
|
||||
'none', False)
|
||||
self.world.difficulty_requirements = difficulties['normal']
|
||||
create_inverted_regions(self.world, 1)
|
||||
create_dungeons(self.world, 1)
|
||||
|
||||
#TODO: Just making sure I haven't missed an entrance. It would be good to test the rules make sense as well.
|
||||
def testInvertedBombRulesAreComplete(self):
|
||||
entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors)
|
||||
must_exits = list(Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit)
|
||||
for entrance_name in (entrances + must_exits):
|
||||
if entrance_name not in ['Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']:
|
||||
entrance = self.world.get_entrance(entrance_name, 1)
|
||||
connect_entrance(self.world, entrance, 'Inverted Big Bomb Shop', 1)
|
||||
set_inverted_big_bomb_rules(self.world, 1)
|
||||
entrance.connected_region.entrances.remove(entrance)
|
||||
entrance.connected_region = None
|
||||
|
||||
def testInvalidEntrancesAreNotUsed(self):
|
||||
entrances = list(Inverted_Blacksmith_Multi_Cave_Doors + Inverted_Blacksmith_Single_Cave_Doors + Inverted_Bomb_Shop_Multi_Cave_Doors + Inverted_Bomb_Shop_Single_Cave_Doors)
|
||||
invalid_entrances = ['Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)', 'Pyramid Fairy']
|
||||
for invalid_entrance in invalid_entrances:
|
||||
self.assertNotIn(invalid_entrance, entrances)
|
||||
|
||||
def testInvalidEntrances(self):
|
||||
for entrance_name in ['Desert Palace Entrance (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']:
|
||||
entrance = self.world.get_entrance(entrance_name, 1)
|
||||
connect_entrance(self.world, entrance, 'Inverted Big Bomb Shop', 1)
|
||||
with self.assertRaises(Exception):
|
||||
set_inverted_big_bomb_rules(self.world, 1)
|
||||
entrance.connected_region.entrances.remove(entrance)
|
||||
entrance.connected_region = None
|
||||
116
test/inverted/TestInvertedDarkWorld.py
Normal file
116
test/inverted/TestInvertedDarkWorld.py
Normal file
@@ -0,0 +1,116 @@
|
||||
from test.inverted.TestInverted import TestInverted
|
||||
|
||||
|
||||
class TestInvertedDeathMountain(TestInverted):
|
||||
|
||||
def testNorthWest(self):
|
||||
self.run_tests([
|
||||
["Brewery", True, []],
|
||||
|
||||
["C-Shaped House", True, []],
|
||||
|
||||
["Chest Game", True, []],
|
||||
|
||||
["Peg Cave", False, []],
|
||||
["Peg Cave", False, [], ['Hammer']],
|
||||
["Peg Cave", False, [], ['Progressive Glove', 'Magic Mirror']],
|
||||
["Peg Cave", True, ['Hammer', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Peg Cave", True, ['Hammer', 'Progressive Glove', 'Magic Mirror', 'Moon Pearl']],
|
||||
["Peg Cave", True, ['Hammer', 'Beat Agahnim 1', 'Magic Mirror']],
|
||||
|
||||
["Bumper Cave Ledge", False, []],
|
||||
["Bumper Cave Ledge", False, [], ['Moon Pearl']],
|
||||
["Bumper Cave Ledge", False, [], ['Cape']],
|
||||
["Bumper Cave Ledge", False, [], ['Progressive Glove']],
|
||||
["Bumper Cave Ledge", False, [], ['Magic Mirror']],
|
||||
["Bumper Cave Ledge", True, ['Moon Pearl', 'Cape', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Bumper Cave Ledge", True, ['Moon Pearl', 'Cape', 'Magic Mirror', 'Progressive Glove', 'Hammer']],
|
||||
["Bumper Cave Ledge", True, ['Moon Pearl', 'Cape', 'Magic Mirror', 'Progressive Glove', 'Beat Agahnim 1']],
|
||||
|
||||
["Blacksmith", False, []],
|
||||
["Blacksmith", False, [], ['Progressive Glove', 'Magic Mirror']],
|
||||
["Blacksmith", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
#@todo: Can get this without moon pearl
|
||||
#["Blacksmith", True, ['Beat Agahnim 1', 'Magic Mirror']],
|
||||
["Blacksmith", True, ['Beat Agahnim 1', 'Magic Mirror', 'Moon Pearl']],
|
||||
["Blacksmith", True, ['Progressive Glove', 'Hammer', 'Magic Mirror', 'Moon Pearl']],
|
||||
|
||||
["Purple Chest", False, []],
|
||||
["Purple Chest", False, [], ['Progressive Glove', 'Magic Mirror']],
|
||||
["Purple Chest", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
# @todo: Can get this without moon pearl
|
||||
#["Purple Chest", True, ['Beat Agahnim 1', 'Magic Mirror']],
|
||||
["Purple Chest", True, ['Beat Agahnim 1', 'Magic Mirror', 'Moon Pearl']],
|
||||
["Purple Chest", True, ['Progressive Glove', 'Hammer', 'Magic Mirror', 'Moon Pearl']],
|
||||
])
|
||||
|
||||
def testNorthEast(self):
|
||||
self.run_tests([
|
||||
["Catfish", False, []],
|
||||
["Catfish", False, [], ['Progressive Glove', 'Flippers']],
|
||||
["Catfish", False, [], ['Progressive Glove', 'Magic Mirror']],
|
||||
["Catfish", False, [], ['Progressive Glove', 'Moon Pearl']],
|
||||
["Catfish", True, ['Beat Agahnim 1', 'Magic Mirror', 'Progressive Glove']],
|
||||
["Catfish", True, ['Beat Agahnim 1', 'Moon Pearl', 'Magic Mirror', 'Flippers']],
|
||||
["Catfish", True, ['Progressive Glove', 'Hammer']],
|
||||
["Catfish", True, ['Progressive Glove', 'Flippers']],
|
||||
["Catfish", True, ['Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Moon Pearl']],
|
||||
|
||||
["Pyramid", False, []],
|
||||
["Pyramid", True, ['Beat Agahnim 1', 'Magic Mirror']],
|
||||
["Pyramid", True, ['Hammer']],
|
||||
["Pyramid", True, ['Flippers', 'Progressive Glove']],
|
||||
["Pyramid", True, ['Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Moon Pearl']],
|
||||
|
||||
["Pyramid Fairy - Left", False, []],
|
||||
["Pyramid Fairy - Left", False, [], ['Magic Mirror']],
|
||||
["Pyramid Fairy - Left", False, [], ['Crystal 5']],
|
||||
["Pyramid Fairy - Left", False, [], ['Crystal 6']],
|
||||
["Pyramid Fairy - Left", True, ['Crystal 5', 'Crystal 6', 'Magic Mirror', 'Hammer', 'Progressive Glove', 'Moon Pearl']],
|
||||
["Pyramid Fairy - Left", True, ['Crystal 5', 'Crystal 6', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
["Pyramid Fairy - Left", True, ['Crystal 5', 'Crystal 6', 'Magic Mirror', 'Beat Agahnim 1']],
|
||||
|
||||
["Pyramid Fairy - Right", False, []],
|
||||
["Pyramid Fairy - Right", False, [], ['Magic Mirror']],
|
||||
["Pyramid Fairy - Right", False, [], ['Crystal 5']],
|
||||
["Pyramid Fairy - Right", False, [], ['Crystal 6']],
|
||||
["Pyramid Fairy - Right", True, ['Crystal 5', 'Crystal 6', 'Magic Mirror', 'Hammer', 'Progressive Glove', 'Moon Pearl']],
|
||||
["Pyramid Fairy - Right", True, ['Crystal 5', 'Crystal 6', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
["Pyramid Fairy - Right", True, ['Crystal 5', 'Crystal 6', 'Magic Mirror', 'Beat Agahnim 1']],
|
||||
])
|
||||
|
||||
def testSouth(self):
|
||||
self.run_tests([
|
||||
["Hype Cave - Top", True, []],
|
||||
|
||||
["Hype Cave - Middle Right", True, []],
|
||||
|
||||
["Hype Cave - Middle Left", True, []],
|
||||
|
||||
["Hype Cave - Bottom", True, []],
|
||||
|
||||
["Hype Cave - Generous Guy", True, []],
|
||||
|
||||
["Stumpy", True, []],
|
||||
|
||||
["Digging Game", True, []],
|
||||
|
||||
["Link's House", True, []],
|
||||
])
|
||||
|
||||
def testMireArea(self):
|
||||
self.run_tests([
|
||||
["Mire Shed - Left", False, []],
|
||||
["Mire Shed - Left", False, [], ['Ocarina', 'Magic Mirror']],
|
||||
["Mire Shed - Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Mire Shed - Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Hammer']],
|
||||
["Mire Shed - Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1']],
|
||||
["Mire Shed - Left", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
||||
|
||||
["Mire Shed - Right", False, []],
|
||||
["Mire Shed - Right", False, [], ['Ocarina', 'Magic Mirror']],
|
||||
["Mire Shed - Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Mire Shed - Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Hammer']],
|
||||
["Mire Shed - Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1']],
|
||||
["Mire Shed - Right", True, ['Magic Mirror', 'Beat Agahnim 1']],
|
||||
])
|
||||
229
test/inverted/TestInvertedDeathMountain.py
Normal file
229
test/inverted/TestInvertedDeathMountain.py
Normal file
@@ -0,0 +1,229 @@
|
||||
from test.inverted.TestInverted import TestInverted
|
||||
|
||||
|
||||
class TestInvertedDeathMountain(TestInverted):
|
||||
|
||||
def testWestDeathMountain(self):
|
||||
self.run_tests([
|
||||
["Old Man", False, []],
|
||||
["Old Man", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Old Man", False, [], ['Lamp']],
|
||||
["Old Man", True, ['Progressive Glove', 'Lamp']],
|
||||
["Old Man", False, ['Ocarina', 'Lamp']],
|
||||
|
||||
["Spectacle Rock Cave", False, []],
|
||||
["Spectacle Rock Cave", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Spectacle Rock Cave", False, [], ['Lamp', 'Ocarina']],
|
||||
["Spectacle Rock Cave", False, ['Ocarina', 'Progressive Glove', 'Hammer']],
|
||||
["Spectacle Rock Cave", False, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||
["Spectacle Rock Cave", False, ['Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Spectacle Rock Cave", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Spectacle Rock Cave", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Spectacle Rock Cave", True, ['Progressive Glove', 'Lamp']],
|
||||
])
|
||||
|
||||
def testEastDeathMountain(self):
|
||||
self.run_tests([
|
||||
["Spiral Cave", False, []],
|
||||
["Spiral Cave", False, [], ['Moon Pearl']],
|
||||
["Spiral Cave", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Spiral Cave", False, [], ['Lamp', 'Ocarina']],
|
||||
["Spiral Cave", False, ['Progressive Glove'], ['Hookshot', 'Progressive Glove']],
|
||||
["Spiral Cave", False, ['Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||
["Spiral Cave", False, ['Progressive Glove', 'Hookshot', 'Moon Pearl']],
|
||||
["Spiral Cave", False, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Spiral Cave", False, ['Ocarina', 'Hookshot', 'Moon Pearl']],
|
||||
["Spiral Cave", True, ['Ocarina', 'Hookshot', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Spiral Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hookshot']],
|
||||
["Spiral Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl']],
|
||||
["Spiral Cave", True, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Lower - Far Left", False, []],
|
||||
["Paradox Cave Lower - Far Left", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Lower - Far Left", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Lower - Far Left", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Lower - Far Left", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Lower - Left", False, []],
|
||||
["Paradox Cave Lower - Left", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Lower - Left", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Lower - Left", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Lower - Left", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Lower - Middle", False, []],
|
||||
["Paradox Cave Lower - Middle", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Lower - Middle", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Lower - Middle", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Lower - Middle", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Lower - Right", False, []],
|
||||
["Paradox Cave Lower - Right", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Lower - Right", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Lower - Right", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Lower - Right", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Lower - Far Right", False, []],
|
||||
["Paradox Cave Lower - Far Right", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Lower - Far Right", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Lower - Far Right", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Lower - Far Right", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Upper - Left", False, []],
|
||||
["Paradox Cave Upper - Left", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Upper - Left", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Upper - Left", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Upper - Left", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Paradox Cave Upper - Right", False, []],
|
||||
["Paradox Cave Upper - Right", False, [], ['Moon Pearl']],
|
||||
["Paradox Cave Upper - Right", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Paradox Cave Upper - Right", False, [], ['Lamp', 'Ocarina']],
|
||||
["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, ['Ocarina', 'Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Paradox Cave Upper - Right", True, ['Ocarina', 'Progressive Glove', 'Hammer', '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, ['Ocarina', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Mimic Cave", False, []],
|
||||
["Mimic Cave", False, [], ['Moon Pearl']],
|
||||
["Mimic Cave", False, [], ['Hammer']],
|
||||
["Mimic Cave", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Mimic Cave", False, [], ['Lamp', 'Ocarina']],
|
||||
["Mimic Cave", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot']],
|
||||
["Mimic Cave", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||
["Mimic Cave", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||
["Mimic Cave", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
||||
|
||||
["Ether Tablet", False, []],
|
||||
["Ether Tablet", False, [], ['Moon Pearl']],
|
||||
["Ether Tablet", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Ether Tablet", False, [], ['Lamp', 'Ocarina']],
|
||||
["Ether Tablet", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||
["Ether Tablet", False, [], ['Hammer']],
|
||||
["Ether Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||
["Ether Tablet", False, [], ['Book of Mudora']],
|
||||
["Ether Tablet", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||
["Ether Tablet", True, ['Ocarina', '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', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Book of Mudora', 'Progressive Sword', 'Progressive Sword']],
|
||||
|
||||
["Spectacle Rock", False, []],
|
||||
["Spectacle Rock", False, [], ['Moon Pearl']],
|
||||
["Spectacle Rock", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Spectacle Rock", False, [], ['Lamp', 'Ocarina']],
|
||||
["Spectacle Rock", False, ['Progressive Glove'], ['Progressive Glove', 'Hookshot']],
|
||||
["Spectacle Rock", False, [], ['Hammer']],
|
||||
["Spectacle Rock", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Hammer', 'Hookshot']],
|
||||
["Spectacle Rock", True, ['Ocarina', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove', 'Hammer']],
|
||||
["Spectacle Rock", True, ['Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer', 'Hookshot']],
|
||||
["Spectacle Rock", True, ['Progressive Glove', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Hammer']],
|
||||
])
|
||||
|
||||
def testEastDarkWorldDeathMountain(self):
|
||||
self.run_tests([
|
||||
["Superbunny Cave - Top", False, []],
|
||||
["Superbunny Cave - Top", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Superbunny Cave - Top", True, ['Progressive Glove', 'Lamp']],
|
||||
["Superbunny Cave - Top", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Ocarina']],
|
||||
["Superbunny Cave - Top", True, ['Hammer', 'Progressive Glove', 'Moon Pearl', 'Ocarina']],
|
||||
|
||||
["Superbunny Cave - Bottom", False, []],
|
||||
["Superbunny Cave - Bottom", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Lamp']],
|
||||
["Superbunny Cave - Bottom", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Ocarina']],
|
||||
["Superbunny Cave - Bottom", True, ['Hammer', 'Progressive Glove', 'Moon Pearl', 'Ocarina']],
|
||||
|
||||
["Hookshot Cave - Bottom Right", False, []],
|
||||
["Hookshot Cave - Bottom Right", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["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', 'Progressive Glove', 'Moon Pearl', 'Ocarina', 'Pegasus Boots']],
|
||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Ocarina', 'Pegasus Boots']],
|
||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
["Hookshot Cave - Bottom Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
|
||||
["Hookshot Cave - Bottom Left", False, []],
|
||||
["Hookshot Cave - Bottom Left", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Hookshot Cave - Bottom Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
["Hookshot Cave - Bottom Left", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
|
||||
["Hookshot Cave - Top Left", False, []],
|
||||
["Hookshot Cave - Top Left", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Hookshot Cave - Top Left", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
["Hookshot Cave - Top Left", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
|
||||
["Hookshot Cave - Top Right", False, []],
|
||||
["Hookshot Cave - Top Right", False, [], ['Progressive Glove', 'Ocarina']],
|
||||
["Hookshot Cave - Top Right", False, [], ['Pegasus Boots', 'Hookshot']],
|
||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Lamp', 'Hookshot']],
|
||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
["Hookshot Cave - Top Right", True, ['Progressive Glove', 'Hammer', 'Moon Pearl', 'Ocarina', 'Hookshot']],
|
||||
])
|
||||
|
||||
def testWestDarkWorldDeathMountain(self):
|
||||
self.run_tests([
|
||||
["Spike Cave", False, []],
|
||||
["Spike Cave", False, [], ['Progressive Glove']],
|
||||
["Spike Cave", False, [], ['Hammer']],
|
||||
["Spike Cave", False, [], ['Cape', 'Cane of Byrna']],
|
||||
["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, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Cape']],
|
||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Lamp', 'Moon Pearl', 'Cape']],
|
||||
["Spike Cave", True, ['Bottle', 'Hammer', 'Progressive Glove', 'Ocarina', 'Moon Pearl', 'Cape']],
|
||||
["Spike Cave", False, ['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', 'Ocarina', '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', 'Ocarina', 'Moon Pearl', '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', 'Ocarina', 'Moon Pearl', 'Cane of Byrna']],
|
||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Lamp', 'Cane of Byrna']],
|
||||
["Spike Cave", True, ['Pegasus Boots', 'Hammer', 'Progressive Glove', 'Ocarina', 'Moon Pearl', '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', 'Ocarina', 'Moon Pearl', 'Cane of Byrna']],
|
||||
])
|
||||
|
||||
380
test/inverted/TestInvertedLightWorld.py
Normal file
380
test/inverted/TestInvertedLightWorld.py
Normal file
@@ -0,0 +1,380 @@
|
||||
from test.inverted.TestInverted import TestInverted
|
||||
|
||||
|
||||
class TestInvertedLightWorld(TestInverted):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
def testLostWoods(self):
|
||||
self.run_tests([
|
||||
["Master Sword Pedestal", False, []],
|
||||
["Master Sword Pedestal", False, [], ['Green Pendant']],
|
||||
["Master Sword Pedestal", False, [], ['Red Pendant']],
|
||||
["Master Sword Pedestal", False, [], ['Blue Pendant']],
|
||||
# @todo: Can get this without moon pearl
|
||||
# ["Master Sword Pedestal", True, ['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1']],
|
||||
["Master Sword Pedestal", True, ['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Beat Agahnim 1', 'Moon Pearl']],
|
||||
["Master Sword Pedestal", True, ['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Master Sword Pedestal", True, ['Green Pendant', 'Red Pendant', 'Blue Pendant', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Mushroom", False, []],
|
||||
["Mushroom", False, [], ['Moon Pearl']],
|
||||
["Mushroom", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Mushroom", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Mushroom", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Lost Woods Hideout", False, []],
|
||||
["Lost Woods Hideout", False, [], ['Moon Pearl']],
|
||||
["Lost Woods Hideout", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Lost Woods Hideout", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Lost Woods Hideout", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Lumberjack Tree", False, []],
|
||||
["Lumberjack Tree", False, [], ['Pegasus Boots']],
|
||||
["Lumberjack Tree", False, [], ['Beat Agahnim 1']],
|
||||
["Lumberjack Tree", False, [], ['Moon Pearl']],
|
||||
["Lumberjack Tree", True, ['Pegasus Boots', 'Beat Agahnim 1', 'Moon Pearl']],
|
||||
])
|
||||
|
||||
def testKakariko(self):
|
||||
self.run_tests([
|
||||
["Kakariko Tavern", False, []],
|
||||
["Kakariko Tavern", False, [], ['Moon Pearl']],
|
||||
["Kakariko Tavern", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Kakariko Tavern", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Kakariko Tavern", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Chicken House", False, []],
|
||||
["Chicken House", False, [], ['Moon Pearl']],
|
||||
["Chicken House", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Chicken House", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Chicken House", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Kakariko Well - Top", False, []],
|
||||
["Kakariko Well - Top", False, [], ['Moon Pearl']],
|
||||
["Kakariko Well - Top", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Kakariko Well - Top", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Kakariko Well - Top", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Kakariko Well - Left", False, []],
|
||||
["Kakariko Well - Left", False, [], ['Moon Pearl']],
|
||||
["Kakariko Well - Left", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Kakariko Well - Left", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Kakariko Well - Left", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Kakariko Well - Middle", False, []],
|
||||
["Kakariko Well - Middle", False, [], ['Moon Pearl']],
|
||||
["Kakariko Well - Middle", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Kakariko Well - Middle", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Kakariko Well - Middle", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Kakariko Well - Right", False, []],
|
||||
["Kakariko Well - Right", False, [], ['Moon Pearl']],
|
||||
["Kakariko Well - Right", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Kakariko Well - Right", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Kakariko Well - Right", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Kakariko Well - Bottom", False, []],
|
||||
["Kakariko Well - Bottom", False, [], ['Moon Pearl']],
|
||||
["Kakariko Well - Bottom", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Kakariko Well - Bottom", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Kakariko Well - Bottom", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Blind's Hideout - Top", False, []],
|
||||
["Blind's Hideout - Top", False, [], ['Moon Pearl']],
|
||||
["Blind's Hideout - Top", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Blind's Hideout - Top", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Blind's Hideout - Top", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Blind's Hideout - Left", False, []],
|
||||
["Blind's Hideout - Left", False, [], ['Moon Pearl']],
|
||||
["Blind's Hideout - Left", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Blind's Hideout - Left", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Blind's Hideout - Left", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Blind's Hideout - Right", False, []],
|
||||
["Blind's Hideout - Right", False, [], ['Moon Pearl']],
|
||||
["Blind's Hideout - Right", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Blind's Hideout - Right", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Blind's Hideout - Right", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Blind's Hideout - Far Left", False, []],
|
||||
["Blind's Hideout - Far Left", False, [], ['Moon Pearl']],
|
||||
["Blind's Hideout - Far Left", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Blind's Hideout - Far Left", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Blind's Hideout - Far Left", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Blind's Hideout - Far Right", False, []],
|
||||
["Blind's Hideout - Far Right", False, [], ['Moon Pearl']],
|
||||
["Blind's Hideout - Far Right", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Blind's Hideout - Far Right", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Blind's Hideout - Far Right", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Bottle Merchant", False, []],
|
||||
#@todo: Can get this without moon pearl
|
||||
#["Bottle Merchant", True, ['Beat Agahnim 1']],
|
||||
["Bottle Merchant", True, ['Beat Agahnim 1', 'Moon Pearl']],
|
||||
["Bottle Merchant", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Bottle Merchant", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Sick Kid", False, []],
|
||||
["Sick Kid", False, [], ['AnyBottle']],
|
||||
["Sick Kid", False, ['Bottle (Bee)']],
|
||||
["Sick Kid", False, ['Bottle (Fairy)']],
|
||||
["Sick Kid", False, ['Bottle (Red Potion)']],
|
||||
["Sick Kid", False, ['Bottle (Green Potion)']],
|
||||
["Sick Kid", False, ['Bottle (Blue Potion)']],
|
||||
["Sick Kid", False, ['Bottle']],
|
||||
["Sick Kid", False, ['Bottle (Good Bee)']],
|
||||
["Sick Kid", True, ['Bottle (Bee)', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle (Bee)', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle (Bee)', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Sick Kid", True, ['Bottle (Fairy)', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle (Fairy)', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle (Fairy)', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Sick Kid", True, ['Bottle (Red Potion)', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle (Red Potion)', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle (Red Potion)', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Sick Kid", True, ['Bottle (Green Potion)', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle (Green Potion)', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle (Green Potion)', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Sick Kid", True, ['Bottle (Blue Potion)', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle (Blue Potion)', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle (Blue Potion)', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Sick Kid", True, ['Bottle', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Sick Kid", True, ['Bottle (Good Bee)', 'Beat Agahnim 1']],
|
||||
["Sick Kid", True, ['Bottle (Good Bee)', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sick Kid", True, ['Bottle (Good Bee)', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Magic Bat", False, []],
|
||||
["Magic Bat", False, [], ['Magic Powder']],
|
||||
["Magic Bat", False, [], ['Hammer']],
|
||||
["Magic Bat", False, [], ['Moon Pearl']],
|
||||
["Magic Bat", False, ['Magic Powder', 'Hammer', 'Moon Pearl']],
|
||||
["Magic Bat", True, ['Magic Powder', 'Hammer', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Magic Bat", True, ['Magic Powder', 'Hammer', 'Moon Pearl', 'Progressive Glove']],
|
||||
|
||||
["Library", False, []],
|
||||
["Library", False, [], ['Pegasus Boots']],
|
||||
["Library", False, [], ['Moon Pearl']],
|
||||
["Library", True, ['Pegasus Boots', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Library", True, ['Pegasus Boots', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Library", True, ['Pegasus Boots', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Maze Race", False, []],
|
||||
["Maze Race", False, [], ['Moon Pearl']],
|
||||
["Maze Race", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Maze Race", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Maze Race", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
])
|
||||
|
||||
def testSouthLightWorld(self):
|
||||
self.run_tests([
|
||||
["Desert Ledge", False, []],
|
||||
["Desert Ledge", False, [], ['Book of Mudora']],
|
||||
["Desert Ledge", False, [], ['Moon Pearl']],
|
||||
["Desert Ledge", True, ['Book of Mudora', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Desert Ledge", True, ['Book of Mudora', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Desert Ledge", True, ['Book of Mudora', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Checkerboard Cave", False, []],
|
||||
["Checkerboard Cave", False, [], ['Progressive Glove']],
|
||||
["Checkerboard Cave", False, [], ['Moon Pearl']],
|
||||
["Checkerboard Cave", True, ['Progressive Glove', 'Beat Agahnim 1', 'Moon Pearl']],
|
||||
["Checkerboard Cave", True, ['Progressive Glove', 'Hammer', 'Moon Pearl']],
|
||||
["Checkerboard Cave", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Aginah's Cave", False, []],
|
||||
["Aginah's Cave", False, [], ['Moon Pearl']],
|
||||
["Aginah's Cave", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Aginah's Cave", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Aginah's Cave", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Bombos Tablet", False, []],
|
||||
["Bombos Tablet", False, ['Progressive Sword'], ['Progressive Sword']],
|
||||
["Bombos Tablet", False, [], ['Book of Mudora']],
|
||||
["Bombos Tablet", False, [], ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["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', 'Hammer', 'Progressive Sword', 'Progressive Sword']],
|
||||
["Bombos Tablet", True, ['Moon Pearl', 'Book of Mudora', 'Beat Agahnim 1', 'Progressive Sword', 'Progressive Sword']],
|
||||
|
||||
["Floodgate Chest", False, []],
|
||||
["Floodgate Chest", False, [], ['Moon Pearl']],
|
||||
["Floodgate Chest", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Floodgate Chest", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Floodgate Chest", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Sunken Treasure", False, []],
|
||||
["Sunken Treasure", False, [], ['Moon Pearl']],
|
||||
["Sunken Treasure", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Sunken Treasure", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sunken Treasure", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Mini Moldorm Cave - Far Left", False, []],
|
||||
["Mini Moldorm Cave - Far Left", False, [], ['Moon Pearl']],
|
||||
["Mini Moldorm Cave - Far Left", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Mini Moldorm Cave - Far Left", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Mini Moldorm Cave - Far Left", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Mini Moldorm Cave - Left", False, []],
|
||||
["Mini Moldorm Cave - Left", False, [], ['Moon Pearl']],
|
||||
["Mini Moldorm Cave - Left", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Mini Moldorm Cave - Left", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Mini Moldorm Cave - Left", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Mini Moldorm Cave - Generous Guy", False, []],
|
||||
["Mini Moldorm Cave - Generous Guy", False, [], ['Moon Pearl']],
|
||||
["Mini Moldorm Cave - Generous Guy", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Mini Moldorm Cave - Generous Guy", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Mini Moldorm Cave - Generous Guy", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Mini Moldorm Cave - Right", False, []],
|
||||
["Mini Moldorm Cave - Right", False, [], ['Moon Pearl']],
|
||||
["Mini Moldorm Cave - Right", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Mini Moldorm Cave - Right", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Mini Moldorm Cave - Right", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Mini Moldorm Cave - Far Right", False, []],
|
||||
["Mini Moldorm Cave - Far Right", False, [], ['Moon Pearl']],
|
||||
["Mini Moldorm Cave - Far Right", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Mini Moldorm Cave - Far Right", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Mini Moldorm Cave - Far Right", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Ice Rod Cave", False, []],
|
||||
["Ice Rod Cave", False, [], ['Moon Pearl']],
|
||||
["Ice Rod Cave", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Ice Rod Cave", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Ice Rod Cave", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
])
|
||||
|
||||
def testZoraArea(self):
|
||||
self.run_tests([
|
||||
["King Zora", False, []],
|
||||
["King Zora", False, [], ['Progressive Glove', 'Flippers']],
|
||||
["King Zora", False, [], ['Moon Pearl']],
|
||||
["King Zora", True, ['Flippers', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["King Zora", True, ['Progressive Glove', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["King Zora", True, ['Progressive Glove', 'Moon Pearl', 'Hammer']],
|
||||
["King Zora", True, ['Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Zora's Ledge", False, []],
|
||||
["Zora's Ledge", False, [], ['Flippers']],
|
||||
["Zora's Ledge", False, [], ['Moon Pearl']],
|
||||
["Zora's Ledge", True, ['Flippers', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Zora's Ledge", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Zora's Ledge", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Waterfall Fairy - Left", False, []],
|
||||
["Waterfall Fairy - Left", False, [], ['Flippers']],
|
||||
["Waterfall Fairy - Left", False, [], ['Moon Pearl']],
|
||||
["Waterfall Fairy - Left", True, ['Flippers', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Waterfall Fairy - Left", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Waterfall Fairy - Left", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Waterfall Fairy - Right", False, []],
|
||||
["Waterfall Fairy - Right", False, [], ['Flippers']],
|
||||
["Waterfall Fairy - Right", False, [], ['Moon Pearl']],
|
||||
["Waterfall Fairy - Right", True, ['Flippers', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Waterfall Fairy - Right", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Waterfall Fairy - Right", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
])
|
||||
|
||||
def testLightWorld(self):
|
||||
self.run_tests([
|
||||
["Link's Uncle", False, []],
|
||||
["Link's Uncle", False, [], ['Moon Pearl']],
|
||||
["Link's Uncle", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Link's Uncle", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Link's Uncle", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Secret Passage", False, []],
|
||||
["Secret Passage", False, [], ['Moon Pearl']],
|
||||
["Secret Passage", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Secret Passage", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Secret Passage", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["King's Tomb", False, []],
|
||||
["King's Tomb", False, [], ['Pegasus Boots']],
|
||||
["King's Tomb", False, ['Progressive Glove'], ['Progressive Glove']],
|
||||
["King's Tomb", False, [], ['Moon Pearl']],
|
||||
["King's Tomb", True, ['Pegasus Boots', 'Progressive Glove', 'Progressive Glove', 'Moon Pearl']],
|
||||
|
||||
["Sahasrahla's Hut - Left", False, []],
|
||||
["Sahasrahla's Hut - Left", False, [], ['Moon Pearl']],
|
||||
["Sahasrahla's Hut - Left", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Sahasrahla's Hut - Left", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sahasrahla's Hut - Left", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Sahasrahla's Hut - Middle", False, []],
|
||||
["Sahasrahla's Hut - Middle", False, [], ['Moon Pearl']],
|
||||
["Sahasrahla's Hut - Middle", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Sahasrahla's Hut - Middle", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sahasrahla's Hut - Middle", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Sahasrahla's Hut - Right", False, []],
|
||||
["Sahasrahla's Hut - Right", False, [], ['Moon Pearl']],
|
||||
["Sahasrahla's Hut - Right", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Sahasrahla's Hut - Right", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sahasrahla's Hut - Right", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Sahasrahla", False, []],
|
||||
["Sahasrahla", False, [], ['Green Pendant']],
|
||||
["Sahasrahla", True, ['Green Pendant', 'Beat Agahnim 1']],
|
||||
["Sahasrahla", True, ['Green Pendant', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Sahasrahla", True, ['Green Pendant', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Bonk Rock Cave", False, []],
|
||||
["Bonk Rock Cave", False, [], ['Pegasus Boots']],
|
||||
["Bonk Rock Cave", False, [], ['Moon Pearl']],
|
||||
["Bonk Rock Cave", True, ['Pegasus Boots', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Bonk Rock Cave", True, ['Pegasus Boots', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Bonk Rock Cave", True, ['Pegasus Boots', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Hobo", False, []],
|
||||
["Hobo", False, [], ['Flippers']],
|
||||
["Hobo", False, [], ['Flippers', 'Moon Pearl']],
|
||||
["Hobo", True, ['Flippers', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Hobo", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Hobo", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Cave 45", False, []],
|
||||
["Cave 45", False, [], ['Moon Pearl']],
|
||||
["Cave 45", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Cave 45", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Cave 45", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
|
||||
["Graveyard Cave", False, []],
|
||||
["Graveyard Cave", False, [], ['Moon Pearl']],
|
||||
["Graveyard Cave", True, ['Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Graveyard Cave", True, ['Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Graveyard Cave", True, ['Moon Pearl', 'Beat Agahnim 1']],
|
||||
|
||||
["Potion Shop", False, []],
|
||||
["Potion Shop", False, [], ['Mushroom']],
|
||||
["Potion Shop", False, [], ['Moon Pearl']],
|
||||
["Potion Shop", True, ['Mushroom', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Potion Shop", True, ['Mushroom', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Potion Shop", True, ['Mushroom', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Lake Hylia Island", False, []],
|
||||
["Lake Hylia Island", False, [], ['Moon Pearl']],
|
||||
["Lake Hylia Island", False, [], ['Flippers']],
|
||||
["Lake Hylia Island", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
["Lake Hylia Island", True, ['Flippers', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Lake Hylia Island", True, ['Flippers', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
|
||||
["Flute Spot", False, []],
|
||||
["Flute Spot", False, [], ['Shovel']],
|
||||
["Flute Spot", False, [], ['Moon Pearl']],
|
||||
["Flute Spot", True, ['Shovel', 'Moon Pearl', 'Beat Agahnim 1']],
|
||||
["Flute Spot", True, ['Shovel', 'Moon Pearl', 'Progressive Glove', 'Hammer']],
|
||||
["Flute Spot", True, ['Shovel', 'Moon Pearl', 'Progressive Glove', 'Progressive Glove']],
|
||||
|
||||
["Ganon", False, []],
|
||||
["Ganon", False, [], ['Moon Pearl']],
|
||||
["Ganon", False, [], ['Beat Agahnim 2']],
|
||||
])
|
||||
207
test/inverted/TestInvertedTurtleRock.py
Normal file
207
test/inverted/TestInvertedTurtleRock.py
Normal file
@@ -0,0 +1,207 @@
|
||||
from test.inverted.TestInverted import TestInverted
|
||||
|
||||
|
||||
class TestInvertedTurtleRock(TestInverted):
|
||||
|
||||
def testTurtleRock(self):
|
||||
self.run_tests([
|
||||
["Turtle Rock - Compass Chest", False, []],
|
||||
["Turtle Rock - Compass Chest", False, [], ['Cane of Somaria']],
|
||||
["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", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', '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', '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', 'Ocarina', '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', 'Ocarina', '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, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||
#@todo: Item rando only needs 1 key
|
||||
["Turtle Rock - Chain Chomps", False, ['Small Key (Turtle Rock)', 'Small Key (Turtle Rock)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Ocarina', '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 - Chain Chomps", 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 - 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, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
||||
["Turtle Rock - Chain Chomps", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror']],
|
||||
|
||||
["Turtle Rock - Roller Room - Left", False, []],
|
||||
["Turtle Rock - Roller Room - Left", False, [], ['Cane of Somaria']],
|
||||
["Turtle Rock - Roller Room - Left", False, [], ['Fire Rod']],
|
||||
["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", True, ['Fire Rod', 'Moon Pearl', 'Ocarina', 'Beat Agahnim 1', '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', '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', 'Ocarina', '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, ['Fire Rod', 'Moon Pearl', 'Ocarina', '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, [], ['Cane of Somaria']],
|
||||
["Turtle Rock - Roller Room - Right", False, [], ['Fire Rod']],
|
||||
["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", True, ['Fire Rod', 'Moon Pearl', 'Ocarina', 'Beat Agahnim 1', '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', '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', 'Ocarina', '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, ['Fire Rod', 'Moon Pearl', 'Ocarina', '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, [], ['Big Key (Turtle Rock)']],
|
||||
["Turtle Rock - Big Chest", False, [], ['Magic Mirror', 'Cane of Somaria']],
|
||||
["Turtle Rock - Big Chest", False, ['Small Key (Turtle Rock)', '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', 'Ocarina', '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 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)', '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', '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', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria']],
|
||||
["Turtle Rock - Big Chest", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Hookshot']],
|
||||
|
||||
["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", True, ['Moon Pearl', 'Ocarina', '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, ['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', '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 - Big Key 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 - Big Key Chest", True, ['Moon Pearl', 'Ocarina', '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 - Big Key Chest", True, ['Moon Pearl', 'Ocarina', '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 - Crystaroller Room", False, []],
|
||||
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Magic Mirror']],
|
||||
["Turtle Rock - Crystaroller Room", False, [], ['Big Key (Turtle Rock)', 'Cane of Somaria']],
|
||||
["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, ['Small Key (Turtle Rock)', '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', 'Ocarina', '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 - 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)', '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', 'Moon Pearl', 'Hookshot']],
|
||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot']],
|
||||
["Turtle Rock - Crystaroller Room", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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', 'Moon Pearl', 'Hookshot', 'Cane of Somaria']],
|
||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria']],
|
||||
["Turtle Rock - Crystaroller Room", True, ['Lamp', 'Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria']],
|
||||
|
||||
#@todo: Advanced?
|
||||
["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)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', '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)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', '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 Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Bottom Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', '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)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', '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 Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Top Left", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', '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)', 'Small Key (Turtle Rock)'], ['Magic Mirror', 'Small Key (Turtle Rock)']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', 'Small Key (Turtle Rock)', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Big Key (Turtle Rock)', 'Moon Pearl', 'Ocarina', '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)', '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)', '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 Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cane of Byrna']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Cape']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Progressive Glove', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Lamp', 'Magic Mirror', 'Progressive Glove', 'Moon Pearl', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Ocarina', 'Beat Agahnim 1', 'Magic Mirror', 'Hookshot', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
["Turtle Rock - Eye Bridge - Top Right", True, ['Moon Pearl', 'Ocarina', 'Progressive Glove', 'Progressive Glove', 'Magic Mirror', 'Cane of Somaria', 'Progressive Shield', 'Progressive Shield', 'Progressive Shield']],
|
||||
|
||||
["Turtle Rock - Boss", False, []],
|
||||
["Turtle Rock - Boss", False, [], ['Cane of Somaria']],
|
||||
["Turtle Rock - Boss", False, [], ['Ice Rod']],
|
||||
["Turtle Rock - Boss", False, [], ['Fire Rod']],
|
||||
["Turtle Rock - Boss", False, [], ['Progressive Sword', 'Hammer']],
|
||||
["Turtle Rock - Boss", False, [], ['Big Key (Turtle Rock)']],
|
||||
["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", True, ['Ice Rod', 'Fire Rod', 'Lamp', 'Moon Pearl', 'Ocarina', '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', 'Moon Pearl', 'Beat Agahnim 1', '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', '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', 'Ocarina', '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)']]
|
||||
])
|
||||
0
test/inverted/__init__.py
Normal file
0
test/inverted/__init__.py
Normal file
Reference in New Issue
Block a user