Ocarina of Time 7.0 (#1277)

## What is this fixing or adding?
- Adds the majority of OoTR 7.0 features:
  - Pot shuffle, Freestanding item shuffle, Crate shuffle, Beehive shuffle
  - Key rings mode
  - Dungeon shortcuts to speed up dungeons
  - "Regional" shuffle for dungeon items
  - New options for shop pricing in shopsanity
  - Expanded Ganon's Boss Key shuffle options
  - Pre-planted beans
  - Improved Chest Appearance Matches Contents mode
  - Blue Fire Arrows
  - Bonk self-damage
  - Finer control over MQ dungeons and spawn position randomization
- Several bugfixes as a result of the update:
  - Items recognized by the server and valid starting items are now in a 1-to-1 correspondence. In particular, starting with keys is now supported.
  - Entrance randomization success rate improved. Hopefully it is now at 100%. 

Co-authored-by: Zach Parks <zach@alliware.com>
This commit is contained in:
espeon65536 2022-12-10 21:11:40 -06:00 committed by GitHub
parent 2cdd03f786
commit aee0df5359
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
110 changed files with 37691 additions and 18648 deletions

View File

@ -3,6 +3,7 @@ import argparse
import logging
import random
import os
import zipfile
from itertools import chain
from BaseClasses import MultiWorld
@ -217,13 +218,18 @@ def adjust(args):
# Load up the ROM
rom = Rom(file=args.rom, force_use=True)
delete_zootdec = True
elif os.path.splitext(args.rom)[-1] == '.apz5':
elif os.path.splitext(args.rom)[-1] in ['.apz5', '.zpf']:
# Load vanilla ROM
rom = Rom(file=args.vanilla_rom, force_use=True)
apz5_file = args.rom
base_name = os.path.splitext(apz5_file)[0]
# Patch file
apply_patch_file(rom, args.rom)
apply_patch_file(rom, apz5_file,
sub_file=(os.path.basename(base_name) + '.zpf'
if zipfile.is_zipfile(apz5_file)
else None))
else:
raise Exception("Invalid file extension; requires .n64, .z64, .apz5")
raise Exception("Invalid file extension; requires .n64, .z64, .apz5, .zpf")
# Call patch_cosmetics
try:
patch_cosmetics(ootworld, rom)

View File

@ -3,6 +3,7 @@ import json
import os
import multiprocessing
import subprocess
import zipfile
from asyncio import StreamReader, StreamWriter
# CommonClient import first to trigger ModuleUpdater
@ -50,7 +51,7 @@ deathlink_sent_this_death: we interacted with the multiworld on this death, wait
oot_loc_name_to_id = network_data_package["games"]["Ocarina of Time"]["location_name_to_id"]
script_version: int = 2
script_version: int = 3
def get_item_value(ap_id):
return ap_id - 66000
@ -85,6 +86,9 @@ class OoTContext(CommonContext):
self.n64_status = CONNECTION_INITIAL_STATUS
self.awaiting_rom = False
self.location_table = {}
self.collectible_table = {}
self.collectible_override_flags_address = 0
self.collectible_offsets = {}
self.deathlink_enabled = False
self.deathlink_pending = False
self.deathlink_sent_this_death = False
@ -117,6 +121,13 @@ class OoTContext(CommonContext):
self.ui = OoTManager(self)
self.ui_task = asyncio.create_task(self.ui.async_run(), name="UI")
def on_package(self, cmd, args):
if cmd == 'Connected':
slot_data = args.get('slot_data', None)
if slot_data:
self.collectible_override_flags_address = slot_data.get('collectible_override_flags', 0)
self.collectible_offsets = slot_data.get('collectible_flag_offsets', {})
def get_payload(ctx: OoTContext):
if ctx.deathlink_enabled and ctx.deathlink_pending:
@ -125,11 +136,14 @@ def get_payload(ctx: OoTContext):
else:
trigger_death = False
return json.dumps({
payload = json.dumps({
"items": [get_item_value(item.item) for item in ctx.items_received],
"playerNames": [name for (i, name) in ctx.player_names.items() if i != 0],
"triggerDeath": trigger_death
"triggerDeath": trigger_death,
"collectibleOverrides": ctx.collectible_override_flags_address,
"collectibleOffsets": ctx.collectible_offsets
})
return payload
async def parse_payload(payload: dict, ctx: OoTContext, force: bool):
@ -141,6 +155,7 @@ async def parse_payload(payload: dict, ctx: OoTContext, force: bool):
ctx.deathlink_client_override = False
ctx.finished_game = False
ctx.location_table = {}
ctx.collectible_table = {}
ctx.deathlink_pending = False
ctx.deathlink_sent_this_death = False
ctx.auth = payload['playerName']
@ -161,11 +176,17 @@ async def parse_payload(payload: dict, ctx: OoTContext, force: bool):
ctx.finished_game = True
# Locations handling
if ctx.location_table != payload['locations']:
ctx.location_table = payload['locations']
locations = payload['locations']
collectibles = payload['collectibles']
if ctx.location_table != locations or ctx.collectible_table != collectibles:
ctx.location_table = locations
ctx.collectible_table = collectibles
locs1 = [oot_loc_name_to_id[loc] for loc, b in ctx.location_table.items() if b]
locs2 = [int(loc) for loc, b in ctx.collectible_table.items() if b]
await ctx.send_msgs([{
"cmd": "LocationChecks",
"locations": [oot_loc_name_to_id[loc] for loc in ctx.location_table if ctx.location_table[loc]]
"locations": locs1 + locs2
}])
# Deathlink handling
@ -191,13 +212,6 @@ async def n64_sync_task(ctx: OoTContext):
try:
await asyncio.wait_for(writer.drain(), timeout=1.5)
try:
# Data will return a dict with up to six fields:
# 1. str: player name (always)
# 2. int: script version (always)
# 3. bool: deathlink active (always)
# 4. dict[str, bool]: checked locations
# 5. bool: whether Link is currently at 0 HP
# 6. bool: whether the game currently registers as complete
data = await asyncio.wait_for(reader.readline(), timeout=10)
data_decoded = json.loads(data.decode())
reported_version = data_decoded.get('scriptVersion', 0)
@ -270,12 +284,16 @@ async def run_game(romfile):
async def patch_and_run_game(apz5_file):
apz5_file = os.path.abspath(apz5_file)
base_name = os.path.splitext(apz5_file)[0]
decomp_path = base_name + '-decomp.z64'
comp_path = base_name + '.z64'
# Load vanilla ROM, patch file, compress ROM
rom = Rom(Utils.local_path(Utils.get_options()["oot_options"]["rom_file"]))
apply_patch_file(rom, apz5_file)
apply_patch_file(rom, apz5_file,
sub_file=(os.path.basename(base_name) + '.zpf'
if zipfile.is_zipfile(apz5_file)
else None))
rom.write_to_file(decomp_path)
os.chdir(data_path("Compress"))
compress_rom_file(decomp_path, comp_path)

View File

@ -72,6 +72,13 @@ def download_slot_file(room_id, player_id: int):
if name.endswith("info.json"):
fname = name.rsplit("/", 1)[0] + ".zip"
elif slot_data.game == "Ocarina of Time":
stream = io.BytesIO(slot_data.data)
if zipfile.is_zipfile(stream):
with zipfile.ZipFile(stream) as zf:
for name in zf.namelist():
if name.endswith(".zpf"):
fname = name.rsplit(".", 1)[0] + ".apz5"
else: # pre-ootr-7.0 support
fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}_P{slot_data.player_id}_{slot_data.player_name}.apz5"
elif slot_data.game == "VVVVVV":
fname = f"AP_{app.jinja_env.filters['suuid'](room_id)}_SP.apv6"

View File

@ -9,7 +9,7 @@
border-top-left-radius: 4px;
border-top-right-radius: 4px;
padding: 3px 3px 10px;
width: 448px;
width: 480px;
background-color: rgb(60, 114, 157);
}
@ -46,7 +46,7 @@
}
#location-table{
width: 448px;
width: 480px;
border-left: 2px solid #000000;
border-right: 2px solid #000000;
border-bottom: 2px solid #000000;
@ -108,7 +108,7 @@
}
#location-table td:first-child {
width: 272px;
width: 300px;
}
.location-category td:first-child {

View File

@ -636,43 +636,47 @@ def __renderOoTTracker(multisave: Dict[str, Any], room: Room, locations: Dict[in
# Gather dungeon locations
area_id_ranges = {
"Overworld": (67000, 67280),
"Deku Tree": (67281, 67303),
"Dodongo's Cavern": (67304, 67334),
"Jabu Jabu's Belly": (67335, 67359),
"Bottom of the Well": (67360, 67384),
"Forest Temple": (67385, 67420),
"Fire Temple": (67421, 67457),
"Water Temple": (67458, 67484),
"Shadow Temple": (67485, 67532),
"Spirit Temple": (67533, 67582),
"Ice Cavern": (67583, 67596),
"Gerudo Training Ground": (67597, 67635),
"Thieves' Hideout": (67259, 67263),
"Ganon's Castle": (67636, 67673),
"Overworld": ((67000, 67258), (67264, 67280), (67747, 68024), (68054, 68062)),
"Deku Tree": ((67281, 67303), (68063, 68077)),
"Dodongo's Cavern": ((67304, 67334), (68078, 68160)),
"Jabu Jabu's Belly": ((67335, 67359), (68161, 68188)),
"Bottom of the Well": ((67360, 67384), (68189, 68230)),
"Forest Temple": ((67385, 67420), (68231, 68281)),
"Fire Temple": ((67421, 67457), (68282, 68350)),
"Water Temple": ((67458, 67484), (68351, 68483)),
"Shadow Temple": ((67485, 67532), (68484, 68565)),
"Spirit Temple": ((67533, 67582), (68566, 68625)),
"Ice Cavern": ((67583, 67596), (68626, 68649)),
"Gerudo Training Ground": ((67597, 67635), (68650, 68656)),
"Thieves' Hideout": ((67259, 67263), (68025, 68053)),
"Ganon's Castle": ((67636, 67673), (68657, 68705)),
}
def lookup_and_trim(id, area):
full_name = lookup_any_location_id_to_name[id]
if id == 67673:
return full_name[13:] # Ganons Tower Boss Key Chest
if 'Ganons Tower' in full_name:
return full_name
if area not in ["Overworld", "Thieves' Hideout"]:
# trim dungeon name. leaves an extra space that doesn't display, or trims fully for DC/Jabu/GC
return full_name[len(area):]
return full_name
checked_locations = multisave.get("location_checks", {}).get((team, player), set()).intersection(set(locations[player]))
location_info = {area: {lookup_and_trim(id, area): id in checked_locations for id in range(min_id, max_id+1) if id in locations[player]}
for area, (min_id, max_id) in area_id_ranges.items()}
checks_done = {area: len(list(filter(lambda x: x, location_info[area].values()))) for area in area_id_ranges}
checks_in_area = {area: len([id for id in range(min_id, max_id+1) if id in locations[player]])
for area, (min_id, max_id) in area_id_ranges.items()}
# Remove Thieves' Hideout checks from Overworld, since it's in the middle of the range
checks_in_area["Overworld"] -= checks_in_area["Thieves' Hideout"]
checks_done["Overworld"] -= checks_done["Thieves' Hideout"]
for loc in location_info["Thieves' Hideout"]:
del location_info["Overworld"][loc]
location_info = {}
checks_done = {}
checks_in_area = {}
for area, ranges in area_id_ranges.items():
location_info[area] = {}
checks_done[area] = 0
checks_in_area[area] = 0
for r in ranges:
min_id, max_id = r
for id in range(min_id, max_id+1):
if id in locations[player]:
checked = id in checked_locations
location_info[area][lookup_and_trim(id, area)] = checked
checks_in_area[area] += 1
checks_done[area] += checked
checks_done['Total'] = sum(checks_done.values())
checks_in_area['Total'] = sum(checks_in_area.values())
@ -683,25 +687,28 @@ def __renderOoTTracker(multisave: Dict[str, Any], room: Room, locations: Dict[in
if "GS" in lookup_and_trim(id, ''):
display_data["token_count"] += 1
oot_y = ''
oot_x = ''
# Gather small and boss key info
small_key_counts = {
"Forest Temple": inventory[66175],
"Fire Temple": inventory[66176],
"Water Temple": inventory[66177],
"Spirit Temple": inventory[66178],
"Shadow Temple": inventory[66179],
"Bottom of the Well": inventory[66180],
"Gerudo Training Ground": inventory[66181],
"Thieves' Hideout": inventory[66182],
"Ganon's Castle": inventory[66183],
"Forest Temple": oot_y if inventory[66203] else inventory[66175],
"Fire Temple": oot_y if inventory[66204] else inventory[66176],
"Water Temple": oot_y if inventory[66205] else inventory[66177],
"Spirit Temple": oot_y if inventory[66206] else inventory[66178],
"Shadow Temple": oot_y if inventory[66207] else inventory[66179],
"Bottom of the Well": oot_y if inventory[66208] else inventory[66180],
"Gerudo Training Ground": oot_y if inventory[66209] else inventory[66181],
"Thieves' Hideout": oot_y if inventory[66210] else inventory[66182],
"Ganon's Castle": oot_y if inventory[66211] else inventory[66183],
}
boss_key_counts = {
"Forest Temple": '' if inventory[66149] else '',
"Fire Temple": '' if inventory[66150] else '',
"Water Temple": '' if inventory[66151] else '',
"Spirit Temple": '' if inventory[66152] else '',
"Shadow Temple": '' if inventory[66153] else '',
"Ganon's Castle": '' if inventory[66154] else '',
"Forest Temple": oot_y if inventory[66149] else oot_x,
"Fire Temple": oot_y if inventory[66150] else oot_x,
"Water Temple": oot_y if inventory[66151] else oot_x,
"Spirit Temple": oot_y if inventory[66152] else oot_x,
"Shadow Temple": oot_y if inventory[66153] else oot_x,
"Ganon's Castle": oot_y if inventory[66154] else oot_x,
}
# Victory condition

View File

@ -2,8 +2,8 @@ local socket = require("socket")
local json = require('json')
local math = require('math')
local last_modified_date = '2022-07-24' -- Should be the last modified date
local script_version = 2
local last_modified_date = '2022-11-27' -- Should be the last modified date
local script_version = 3
--------------------------------------------------
-- Heavily modified form of RiptideSage's tracker
@ -25,6 +25,9 @@ local inf_table_offset = save_context_offset + 0xEF8 -- 0x11B4C8
local temp_context = nil
local collectibles_overrides = nil
local collectible_offsets = nil
-- Offsets for scenes can be found here
-- https://wiki.cloudmodding.com/oot/Scene_Table/NTSC_1.0
-- Each scene is 0x1c bits long, chests at 0x0, switches at 0x4, collectibles at 0xc
@ -40,12 +43,16 @@ end
-- [1] is the scene id
-- [2] is the location type, which varies as input to the function
-- [3] is the location id within the scene, and represents the bit which was checked
-- REORDERED IN 7.0 TO scene id - location type - 0x00 - location id
-- Note that temp_context is 0-indexed and expected_values is 1-indexed, because consistency.
local check_temp_context = function(expected_values)
if temp_context[0] ~= 0x00 then return false end
for i=1,3 do
if temp_context[i] ~= expected_values[i] then return false end
end
-- if temp_context[0] ~= 0x00 then return false end
-- for i=1,3 do
-- if temp_context[i] ~= expected_values[i] then return false end
-- end
if temp_context[0] ~= expected_values[1] then return false end
if temp_context[1] ~= expected_values[2] then return false end
if temp_context[3] ~= expected_values[3] then return false end
return true
end
@ -67,7 +74,7 @@ local on_the_ground_check = function(scene_offset, bit_to_check)
end
local boss_item_check = function(scene_offset)
return chest_check(scene_offset, 0x1F)
return on_the_ground_check(scene_offset, 0x1F)
or check_temp_context({scene_offset, 0x00, 0x4F})
end
@ -226,6 +233,8 @@ local read_kokiri_forest_checks = function()
checks["KF Shop Item 6"] = shop_check(0x6, 0x1)
checks["KF Shop Item 7"] = shop_check(0x6, 0x2)
checks["KF Shop Item 8"] = shop_check(0x6, 0x3)
checks["KF Shop Blue Rupee"] = on_the_ground_check(0x2D, 0x1)
return checks
end
@ -454,7 +463,7 @@ local read_kakariko_village_checks = function()
checks["Kak Impas House Cow"] = cow_check(0x37, 0x18)
checks["Kak GS Tree"] = skulltula_check(0x10, 0x5)
checks["Kak GS Guards House"] = skulltula_check(0x10, 0x1)
checks["Kak GS Near Gate Guard"] = skulltula_check(0x10, 0x1)
checks["Kak GS Watchtower"] = skulltula_check(0x10, 0x2)
checks["Kak GS Skulltula House"] = skulltula_check(0x10, 0x4)
checks["Kak GS House Under Construction"] = skulltula_check(0x10, 0x3)
@ -480,7 +489,7 @@ local read_graveyard_checks = function()
checks["Graveyard Royal Familys Tomb Chest"] = chest_check(0x41, 0x00)
checks["Graveyard Freestanding PoH"] = on_the_ground_check(0x53, 0x4)
checks["Graveyard Dampe Gravedigging Tour"] = on_the_ground_check(0x53, 0x8)
checks["Graveyard Hookshot Chest"] = chest_check(0x48, 0x00)
checks["Graveyard Dampe Race Hookshot Chest"] = chest_check(0x48, 0x00)
checks["Graveyard Dampe Race Freestanding PoH"] = on_the_ground_check(0x48, 0x7)
checks["Graveyard GS Bean Patch"] = skulltula_check(0x10, 0x0)
@ -545,7 +554,7 @@ local read_shadow_temple_checks = function(mq_table_address)
checks["Shadow Temple Boss Key Chest"] = chest_check(0x07, 0x0B)
checks["Shadow Temple Invisible Floormaster Chest"] = chest_check(0x07, 0x0D)
checks["Shadow Temple GS Like Like Room"] = skulltula_check(0x07, 0x3)
checks["Shadow Temple GS Invisible Blades Room"] = skulltula_check(0x07, 0x3)
checks["Shadow Temple GS Falling Spikes Room"] = skulltula_check(0x07, 0x1)
checks["Shadow Temple GS Single Giant Pot"] = skulltula_check(0x07, 0x0)
checks["Shadow Temple GS Near Ship"] = skulltula_check(0x07, 0x4)
@ -723,9 +732,9 @@ local read_fire_temple_checks = function(mq_table_address)
checks["Fire Temple MQ GS Big Lava Room Open Door"] = skulltula_check(0x4, 0x0)
checks["Fire Temple MQ GS Skull On Fire"] = skulltula_check(0x4, 0x2)
checks["Fire Temple MQ GS Fire Wall Maze Center"] = skulltula_check(0x4, 0x3)
checks["Fire Temple MQ GS Fire Wall Maze Side Room"] = skulltula_check(0x4, 0x4)
checks["Fire Temple MQ GS Above Fire Wall Maze"] = skulltula_check(0x4, 0x1)
checks["Fire Temple MQ GS Flame Maze Center"] = skulltula_check(0x4, 0x3)
checks["Fire Temple MQ GS Flame Maze Side Room"] = skulltula_check(0x4, 0x4)
checks["Fire Temple MQ GS Above Flame Maze"] = skulltula_check(0x4, 0x1)
end
checks["Fire Temple Volvagia Heart"] = boss_item_check(0x15)
@ -743,6 +752,12 @@ local read_zoras_river_checks = function()
checks["ZR Deku Scrub Grotto Front"] = scrub_sanity_check(0x15, 0x9)
checks["ZR Deku Scrub Grotto Rear"] = scrub_sanity_check(0x15, 0x8)
checks["ZR Frogs Zeldas Lullaby"] = event_check(0xD, 0x1)
checks["ZR Frogs Eponas Song"] = event_check(0xD, 0x2)
checks["ZR Frogs Suns Song"] = event_check(0xD, 0x3)
checks["ZR Frogs Sarias Song"] = event_check(0xD, 0x4)
checks["ZR Frogs Song of Time"] = event_check(0xD, 0x5)
checks["ZR GS Tree"] = skulltula_check(0x11, 0x1)
--NOTE: There is no GS in the soft soil. It's the only one that doesn't have one.
checks["ZR GS Ladder"] = skulltula_check(0x11, 0x0)
@ -912,10 +927,10 @@ end
local read_gerudo_fortress_checks = function()
local checks = {}
checks["Hideout Jail Guard (1 Torch)"] = on_the_ground_check(0xC, 0xC)
checks["Hideout Jail Guard (2 Torches)"] = on_the_ground_check(0xC, 0xF)
checks["Hideout Jail Guard (3 Torches)"] = on_the_ground_check(0xC, 0xA)
checks["Hideout Jail Guard (4 Torches)"] = on_the_ground_check(0xC, 0xE)
checks["Hideout 1 Torch Jail Gerudo Key"] = on_the_ground_check(0xC, 0xC)
checks["Hideout 2 Torches Jail Gerudo Key"] = on_the_ground_check(0xC, 0xF)
checks["Hideout 3 Torches Jail Gerudo Key"] = on_the_ground_check(0xC, 0xA)
checks["Hideout 4 Torches Jail Gerudo Key"] = on_the_ground_check(0xC, 0xE)
checks["Hideout Gerudo Membership Card"] = membership_card_check(0xC, 0x2)
checks["GF Chest"] = chest_check(0x5D, 0x0)
checks["GF HBA 1000 Points"] = info_table_check(0x33, 0x0)
@ -1170,9 +1185,22 @@ local check_all_locations = function(mq_table_address)
for k,v in pairs(read_ganons_castle_checks(mq_table_address)) do location_checks[k] = v end
for k,v in pairs(read_outside_ganons_castle_checks()) do location_checks[k] = v end
for k,v in pairs(read_song_checks()) do location_checks[k] = v end
-- write 0 to temp context values
mainmemory.write_u32_be(0x40002C, 0)
mainmemory.write_u32_be(0x400030, 0)
return location_checks
end
local check_collectibles = function()
local retval = {}
if collectible_offsets ~= nil then
for id, data in pairs(collectible_offsets) do
local mem = mainmemory.readbyte(collectible_overrides + data[1] + bit.rshift(data[2], 3))
retval[id] = bit.check(mem, data[2] % 8)
end
end
return retval
end
-- convenience functions
@ -1557,9 +1585,10 @@ local outgoing_player_addr = coop_context + 18
local player_names_address = coop_context + 20
local player_name_length = 8 -- 8 bytes
local rom_name_location = player_names_address + 0x800
local rom_name_location = player_names_address + 0x800 + 0x5 -- 0x800 player names, 0x5 CFG_FILE_SELECT_HASH
local master_quest_table_address = rando_context + (mainmemory.read_u32_be(rando_context + 0x0CE0) - 0x03480000)
-- TODO: load dynamically from slot data
local master_quest_table_address = rando_context + (mainmemory.read_u32_be(rando_context + 0x0E9F) - 0x03480000)
local save_context_addr = 0x11A5D0
local internal_count_addr = save_context_addr + 0x90
@ -1568,7 +1597,7 @@ local item_queue = {}
local first_connect = true
local game_complete = false
NUM_BIG_POES_REQUIRED = mainmemory.read_u8(rando_context + 0x0CEE)
NUM_BIG_POES_REQUIRED = mainmemory.read_u8(rando_context + 0x0EAD)
local bytes_to_string = function(bytes)
local string = ''
@ -1718,7 +1747,7 @@ function is_game_complete()
end
function deathlink_enabled()
local death_link_flag = mainmemory.read_u16_be(coop_context + 0xA)
local death_link_flag = mainmemory.readbyte(coop_context + 0xB)
return death_link_flag > 0
end
@ -1774,6 +1803,13 @@ function process_block(block)
mainmemory.write_u16_be(incoming_item_addr, item_queue[received_items_count+1])
end
end
-- Record collectible data if necessary
if collectible_overrides == nil and block['collectibleOverrides'] ~= 0 then
collectible_overrides = mainmemory.read_u32_be(rando_context + block['collectibleOverrides']) - 0x80000000
end
if collectible_offsets ~= block['collectibleOffsets'] then
collectible_offsets = block['collectibleOffsets']
end
return
end
@ -1805,6 +1841,7 @@ function receive()
retTable["deathlinkActive"] = deathlink_enabled()
if InSafeState() then
retTable["locations"] = check_all_locations(master_quest_table_address)
retTable["collectibles"] = check_collectibles()
retTable["isDead"] = get_death_state()
retTable["gameComplete"] = is_game_complete()
end

View File

@ -39,6 +39,13 @@ def patch_dpad(rom, ootworld, symbols):
rom.write_byte(symbols['CFG_DISPLAY_DPAD'], 0x00)
def patch_dpad_info(rom, ootworld, symbols):
# Display D-Pad HUD in pause menu for either dungeon info or equips
if ootworld.dpad_dungeon_menu:
rom.write_byte(symbols['CFG_DPAD_DUNGEON_INFO_ENABLE'], 0x01)
else:
rom.write_byte(symbols['CFG_DPAD_DUNGEON_INFO_ENABLE'], 0x00)
def patch_music(rom, ootworld, symbols):
# patch music
@ -648,6 +655,7 @@ legacy_cosmetic_data_headers = [
0x03480810,
]
patch_sets = {}
global_patch_sets = [
patch_targeting,
patch_music,
@ -656,12 +664,13 @@ global_patch_sets = [
patch_sword_trails,
patch_gauntlet_colors,
patch_shield_frame_colors,
# patch_voices,
patch_sfx,
patch_instrument,
]
patch_sets = {
0x1F04FA62: {
# 3.14.1
patch_sets[0x1F04FA62] = {
"patches": [
patch_dpad,
patch_sword_trails,
@ -671,22 +680,17 @@ patch_sets = {
"CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0005,
"CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0006,
},
},
0x1F05D3F9: {
"patches": [
patch_dpad,
patch_sword_trails,
],
"symbols": {
"CFG_DISPLAY_DPAD": 0x0004,
"CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0005,
"CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0006,
},
},
0x1F0693FB: {
"patches": [
patch_dpad,
patch_sword_trails,
}
# 3.14.11
patch_sets[0x1F05D3F9] = {
"patches": patch_sets[0x1F04FA62]["patches"] + [],
"symbols": {**patch_sets[0x1F04FA62]["symbols"]},
}
# 4.5.7
patch_sets[0x1F0693FB] = {
"patches": patch_sets[0x1F05D3F9]["patches"] + [
patch_heart_colors,
patch_magic_colors,
],
@ -697,13 +701,11 @@ patch_sets = {
"CFG_RAINBOW_SWORD_INNER_ENABLED": 0x0011,
"CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x0012,
}
},
0x1F073FC9: {
"patches": [
patch_dpad,
patch_sword_trails,
patch_heart_colors,
patch_magic_colors,
}
# 5.2.6
patch_sets[0x1F073FC9] = {
"patches": patch_sets[0x1F0693FB]["patches"] + [
patch_button_colors,
],
"symbols": {
@ -720,28 +722,17 @@ patch_sets = {
"CFG_RAINBOW_SWORD_INNER_ENABLED": 0x003B,
"CFG_RAINBOW_SWORD_OUTER_ENABLED": 0x003C,
}
},
0x1F073FD8: {
"patches": [
patch_dpad,
}
# 5.2.76
patch_sets[0x1F073FD8] = {
"patches": patch_sets[0x1F073FC9]["patches"] + [
patch_navi_colors,
patch_sword_trails,
patch_heart_colors,
patch_magic_colors,
patch_button_colors,
patch_boomerang_trails,
patch_bombchu_trails,
],
"symbols": {
"CFG_MAGIC_COLOR": 0x0004,
"CFG_HEART_COLOR": 0x000A,
"CFG_A_BUTTON_COLOR": 0x0010,
"CFG_B_BUTTON_COLOR": 0x0016,
"CFG_C_BUTTON_COLOR": 0x001C,
"CFG_TEXT_CURSOR_COLOR": 0x0022,
"CFG_SHOP_CURSOR_COLOR": 0x0028,
"CFG_A_NOTE_COLOR": 0x002E,
"CFG_C_NOTE_COLOR": 0x0034,
**patch_sets[0x1F073FC9]["symbols"],
"CFG_BOOM_TRAIL_INNER_COLOR": 0x003A,
"CFG_BOOM_TRAIL_OUTER_COLOR": 0x003D,
"CFG_BOMBCHU_TRAIL_INNER_COLOR": 0x0040,
@ -762,7 +753,17 @@ patch_sets = {
"CFG_RAINBOW_NAVI_PROP_INNER_ENABLED": 0x0053,
"CFG_RAINBOW_NAVI_PROP_OUTER_ENABLED": 0x0054,
}
},
}
# 6.2.218
patch_sets[0x1F073FD9] = {
"patches": patch_sets[0x1F073FD8]["patches"] + [
patch_dpad_info,
],
"symbols": {
**patch_sets[0x1F073FD8]["symbols"],
"CFG_DPAD_DUNGEON_INFO_ENABLE": 0x0055,
}
}

View File

@ -1,22 +1,15 @@
class Dungeon(object):
def __init__(self, world, name, hint, font_color, boss_key, small_keys, dungeon_items):
def to_array(obj):
if obj == None:
return []
if isinstance(obj, list):
return obj
else:
return [obj]
def __init__(self, world, name, hint, font_color):
self.multiworld = world
self.world = world
self.name = name
self.hint_text = hint
self.font_color = font_color
self.regions = []
self.boss_key = to_array(boss_key)
self.small_keys = to_array(small_keys)
self.dungeon_items = to_array(dungeon_items)
self.boss_key = []
self.small_keys = []
self.dungeon_items = []
for region in world.multiworld.regions:
if region.player == world.player and region.dungeon == self.name:
@ -48,6 +41,10 @@ class Dungeon(object):
return item.name in [dungeon_item.name for dungeon_item in self.all_items]
def item_name(self, name):
return f"{name} ({self.name})"
def __str__(self):
return str(self.__unicode__())

View File

@ -136,15 +136,15 @@ def create_dungeons(ootworld):
ootworld.load_regions_from_json(dungeon_json)
boss_keys = [ootworld.create_item(f'Boss Key ({name})') for i in range(dungeon_info['boss_key'])]
if not ootworld.dungeon_mq[dungeon_info['name']]:
small_keys = [ootworld.create_item(f'Small Key ({name})') for i in range(dungeon_info['small_key'])]
else:
small_keys = [ootworld.create_item(f'Small Key ({name})') for i in range(dungeon_info['small_key_mq'])]
dungeon_items = [ootworld.create_item(f'Map ({name})'), ootworld.create_item(f'Compass ({name})')] * dungeon_info['dungeon_item']
if ootworld.shuffle_mapcompass in ['any_dungeon', 'overworld']:
for item in dungeon_items:
item.priority = True
# boss_keys = [ootworld.create_item(f'Boss Key ({name})') for i in range(dungeon_info['boss_key'])]
# if not ootworld.dungeon_mq[dungeon_info['name']]:
# small_keys = [ootworld.create_item(f'Small Key ({name})') for i in range(dungeon_info['small_key'])]
# else:
# small_keys = [ootworld.create_item(f'Small Key ({name})') for i in range(dungeon_info['small_key_mq'])]
# dungeon_items = [ootworld.create_item(f'Map ({name})'), ootworld.create_item(f'Compass ({name})')] * dungeon_info['dungeon_item']
# if ootworld.shuffle_mapcompass in ['any_dungeon', 'overworld']:
# for item in dungeon_items:
# item.priority = True
ootworld.dungeons.append(Dungeon(ootworld, name, hint, font_color, boss_keys, small_keys, dungeon_items))
ootworld.dungeons.append(Dungeon(ootworld, name, hint, font_color))

View File

@ -95,6 +95,8 @@ entrance_shuffle_table = [
('Ice Cavern Beginning -> ZF Ice Ledge', { 'index': 0x03D4 })),
('Dungeon', ('Gerudo Fortress -> Gerudo Training Ground Lobby', { 'index': 0x0008 }),
('Gerudo Training Ground Lobby -> Gerudo Fortress', { 'index': 0x03A8 })),
('DungeonSpecial', ('Ganons Castle Grounds -> Ganons Castle Lobby', { 'index': 0x0467 }),
('Ganons Castle Lobby -> Castle Grounds From Ganons Castle', { 'index': 0x023D })),
('Interior', ('Kokiri Forest -> KF Midos House', { 'index': 0x0433 }),
('KF Midos House -> Kokiri Forest', { 'index': 0x0443 })),
@ -238,8 +240,8 @@ entrance_shuffle_table = [
('KF Storms Grotto -> Kokiri Forest', { 'grotto_id': 0x1B })),
('Grotto', ('Zoras Domain -> ZD Storms Grotto', { 'grotto_id': 0x1C, 'entrance': 0x036D, 'content': 0xFF, 'scene': 0x58 }),
('ZD Storms Grotto -> Zoras Domain', { 'grotto_id': 0x1C })),
('Grotto', ('Gerudo Fortress -> GF Storms Grotto', { 'grotto_id': 0x1D, 'entrance': 0x036D, 'content': 0xFF, 'scene': 0x5D }),
('GF Storms Grotto -> Gerudo Fortress', { 'grotto_id': 0x1D })),
('Grotto', ('GF Entrances Behind Crates -> GF Storms Grotto', { 'grotto_id': 0x1D, 'entrance': 0x036D, 'content': 0xFF, 'scene': 0x5D }),
('GF Storms Grotto -> GF Entrances Behind Crates', { 'grotto_id': 0x1D })),
('Grotto', ('GV Fortress Side -> GV Storms Grotto', { 'grotto_id': 0x1E, 'entrance': 0x05BC, 'content': 0xF0, 'scene': 0x5A }),
('GV Storms Grotto -> GV Fortress Side', { 'grotto_id': 0x1E })),
('Grotto', ('GV Grotto Ledge -> GV Octorok Grotto', { 'grotto_id': 0x1F, 'entrance': 0x05AC, 'content': 0xF2, 'scene': 0x5A }),
@ -263,7 +265,7 @@ entrance_shuffle_table = [
('Overworld', ('Lost Woods -> GC Woods Warp', { 'index': 0x04E2 }),
('GC Woods Warp -> Lost Woods', { 'index': 0x04D6 })),
('Overworld', ('Lost Woods -> Zora River', { 'index': 0x01DD }),
('Zora River -> Lost Woods', { 'index': 0x04DA })),
('Zora River -> LW Underwater Entrance', { 'index': 0x04DA })),
('Overworld', ('LW Beyond Mido -> SFM Entryway', { 'index': 0x00FC }),
('SFM Entryway -> LW Beyond Mido', { 'index': 0x01A9 })),
('Overworld', ('LW Bridge -> Hyrule Field', { 'index': 0x0185 }),
@ -329,6 +331,74 @@ entrance_shuffle_table = [
]
def _add_boss_entrances():
# Compute this at load time to save a lot of duplication
dungeon_data = {}
for type, forward, *reverse in entrance_shuffle_table:
if type != 'Dungeon':
continue
if not reverse:
continue
name, forward = forward
reverse = reverse[0][1]
if 'blue_warp' not in reverse:
continue
dungeon_data[name] = {
'dungeon_index': forward['index'],
'exit_index': reverse['index'],
'exit_blue_warp': reverse['blue_warp']
}
for type, source, target, dungeon, index, rindex, addresses in [
(
'ChildBoss', 'Deku Tree Boss Door', 'Queen Gohma Boss Room',
'KF Outside Deku Tree -> Deku Tree Lobby',
0x040f, 0x0252, [ 0xB06292, 0xBC6162, 0xBC60AE ]
),
(
'ChildBoss', 'Dodongos Cavern Boss Door', 'King Dodongo Boss Room',
'Death Mountain -> Dodongos Cavern Beginning',
0x040b, 0x00c5, [ 0xB062B6, 0xBC616E ]
),
(
'ChildBoss', 'Jabu Jabus Belly Boss Door', 'Barinade Boss Room',
'Zoras Fountain -> Jabu Jabus Belly Beginning',
0x0301, 0x0407, [ 0xB062C2, 0xBC60C2 ]
),
(
'AdultBoss', 'Forest Temple Boss Door', 'Phantom Ganon Boss Room',
'SFM Forest Temple Entrance Ledge -> Forest Temple Lobby',
0x000c, 0x024E, [ 0xB062CE, 0xBC6182 ]
),
(
'AdultBoss', 'Fire Temple Boss Door', 'Volvagia Boss Room',
'DMC Fire Temple Entrance -> Fire Temple Lower',
0x0305, 0x0175, [ 0xB062DA, 0xBC60CE ]
),
(
'AdultBoss', 'Water Temple Boss Door', 'Morpha Boss Room',
'Lake Hylia -> Water Temple Lobby',
0x0417, 0x0423, [ 0xB062E6, 0xBC6196 ]
),
(
'AdultBoss', 'Spirit Temple Boss Door', 'Twinrova Boss Room',
'Desert Colossus -> Spirit Temple Lobby',
0x008D, 0x02F5, [ 0xB062F2, 0xBC6122 ]
),
(
'AdultBoss', 'Shadow Temple Boss Door', 'Bongo Bongo Boss Room',
'Graveyard Warp Pad Region -> Shadow Temple Entryway',
0x0413, 0x02B2, [ 0xB062FE, 0xBC61AA ]
)
]:
d = {'index': index, 'patch_addresses': addresses}
d.update(dungeon_data[dungeon])
entrance_shuffle_table.append(
(type, (f"{source} -> {target}", d), (f"{target} -> {source}", {'index': rindex}))
)
_add_boss_entrances()
# Basically, the entrances in the list above that go to:
# - DMC Central Local (child access for the bean and skull)
# - Desert Colossus (child access to colossus and spirit)
@ -395,11 +465,24 @@ def shuffle_random_entrances(ootworld):
one_way_priorities['Requiem'] = priority_entrance_table['Requiem']
if ootworld.spawn_positions:
one_way_entrance_pools['Spawn'] = ootworld.get_shufflable_entrances(type='Spawn')
if 'child' not in ootworld.spawn_positions:
one_way_entrance_pools['Spawn'].remove(ootworld.get_entrance('Child Spawn -> KF Links House'))
if 'adult' not in ootworld.spawn_positions:
one_way_entrance_pools['Spawn'].remove(ootworld.get_entrance('Adult Spawn -> Temple of Time'))
if ootworld.shuffle_bosses == 'full':
entrance_pools['Boss'] = ootworld.get_shufflable_entrances(type='ChildBoss', only_primary=True)
entrance_pools['Boss'] += ootworld.get_shufflable_entrances(type='AdultBoss', only_primary=True)
elif ootworld.shuffle_bosses == 'limited':
entrance_pools['ChildBoss'] = ootworld.get_shufflable_entrances(type='ChildBoss', only_primary=True)
entrance_pools['AdultBoss'] = ootworld.get_shufflable_entrances(type='AdultBoss', only_primary=True)
if ootworld.shuffle_dungeon_entrances:
entrance_pools['Dungeon'] = ootworld.get_shufflable_entrances(type='Dungeon', only_primary=True)
if ootworld.open_forest == 'closed':
entrance_pools['Dungeon'].remove(world.get_entrance('KF Outside Deku Tree -> Deku Tree Lobby', player))
entrance_pools['Dungeon'].remove(ootworld.get_entrance('KF Outside Deku Tree -> Deku Tree Lobby', player))
if ootworld.shuffle_special_dungeon_entrances:
entrance_pools['Dungeon'] += ootworld.get_shufflable_entrances(type='DungeonSpecial', only_primary=True)
if ootworld.decouple_entrances:
entrance_pools['DungeonReverse'] = [entrance.reverse for entrance in entrance_pools['Dungeon']]
if ootworld.shuffle_interior_entrances != 'off':

View File

@ -147,10 +147,20 @@ conditional_always = {
'Song from Ocarina of Time': lambda world: stones_required_by_settings(world) < 2,
'HF Ocarina of Time Item': lambda world: stones_required_by_settings(world) < 2,
'Sheik in Kakariko': lambda world: medallions_required_by_settings(world) < 5,
'DMT Biggoron': lambda world: world.logic_earliest_adult_trade != 'claim_check' or world.logic_latest_adult_trade != 'claim_check',
'Kak 30 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 30,
'Kak 40 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 40,
'Kak 50 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 50,
'DMT Biggoron': lambda world: world.adult_trade_start != {'Claim Check'},
'Kak 30 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 30 and '30_skulltulas' not in world.misc_hints,
'Kak 40 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 40 and '40_skulltulas' not in world.misc_hints,
'Kak 50 Gold Skulltula Reward': lambda world: tokens_required_by_settings(world) < 50 and '50_skulltulas' not in world.misc_hints,
}
# Entrance hints required under certain settings
conditional_entrance_always = {
'Ganons Castle Grounds -> Ganons Castle Lobby': lambda world: (world.bridge != 'open'
and (world.bridge != 'stones' or world.bridge_stones > 1)
and (world.bridge != 'medallions' or world.bridge_medallions > 1)
and (world.bridge != 'dungeons' or world.bridge_rewards > 2)
and (world.bridge != 'tokens' or world.bridge_tokens > 20)
and (world.bridge != 'hearts' or world.bridge_hearts > world.starting_hearts + 1)),
}
@ -160,7 +170,16 @@ conditional_always = {
# @ will print the player name
# # sets color to white (currently only used for dungeon reward hints).
hintTable = {
'Triforce Piece': (["a triumph fork", "cheese", "a gold fragment"], "a Piece of the Triforce", "item"),
'Kokiri Emerald': (["a tree's farewell", "the Spiritual Stone of the Forest"], "the Kokiri Emerald", 'item'),
'Goron Ruby': (["the Gorons' hidden treasure", "the Spiritual Stone of Fire"], "the Goron Ruby", 'item'),
'Zora Sapphire': (["an engagement ring", "the Spiritual Stone of Water"], "the Zora Sapphire", 'item'),
'Light Medallion': (["Rauru's sagely power", "a yellow disc"], "the Light Medallion", 'item'),
'Forest Medallion': (["Saria's sagely power", "a green disc"], "the Forest Medallion", 'item'),
'Fire Medallion': (["Darunia's sagely power", "a red disc"], "the Fire Medallion", 'item'),
'Water Medallion': (["Ruto's sagely power", "a blue disc"], "the Water Medallion", 'item'),
'Shadow Medallion': (["Impa's sagely power", "a purple disc"], "the Shadow Medallion", 'item'),
'Spirit Medallion': (["Nabooru's sagely power", "an orange disc"], "the Spirit Medallion", 'item'),
'Triforce Piece': (["a triumph fork", "cheese", "a gold fragment"], "a Piece of the Triforce", 'item'),
'Magic Meter': (["mystic training", "pixie dust", "a green rectangle"], "a Magic Meter", 'item'),
'Double Defense': (["a white outline", "damage decrease", "strengthened love"], "Double Defense", 'item'),
'Slingshot': (["a seed shooter", "a rubberband", "a child's catapult"], "a Slingshot", 'item'),
@ -245,11 +264,55 @@ hintTable = {
'Eyedrops': (["a vision vial"], "the Eyedrops", 'item'),
'Claim Check': (["a three day wait"], "the Claim Check", 'item'),
'Map': (["a dungeon atlas", "blueprints"], "a Map", 'item'),
'Map (Deku Tree)': (["an atlas of an ancient tree", "blueprints of an ancient tree"], "a Map of the Deku Tree", 'item'),
'Map (Dodongos Cavern)': (["an atlas of an immense cavern", "blueprints of an immense cavern"], "a Map of Dodongo's Cavern", 'item'),
'Map (Jabu Jabus Belly)': (["an atlas of the belly of a deity", "blueprints of the belly of a deity"], "a Map of Jabu Jabu's Belly", 'item'),
'Map (Forest Temple)': (["an atlas of a deep forest", "blueprints of a deep forest"], "a Map of the Forest Temple", 'item'),
'Map (Fire Temple)': (["an atlas of a high mountain", "blueprints of a high mountain"], "a Map of the Fire Temple", 'item'),
'Map (Water Temple)': (["an atlas of a vast lake", "blueprints of a vast lake"], "a Map of the Water Temple", 'item'),
'Map (Shadow Temple)': (["an atlas of the house of the dead", "blueprints of the house of the dead"], "a Map of the Shadow Temple", 'item'),
'Map (Spirit Temple)': (["an atlas of the goddess of the sand", "blueprints of the goddess of the sand"], "a Map of the Spirit Temple", 'item'),
'Map (Bottom of the Well)': (["an atlas of a shadow's prison", "blueprints of a shadow's prison"], "a Map of the Bottom of the Well", 'item'),
'Map (Ice Cavern)': (["an atlas of a frozen maze", "blueprints of a frozen maze"], "a Map of the Ice Cavern", 'item'),
'Compass': (["a treasure tracker", "a magnetic needle"], "a Compass", 'item'),
'Compass (Deku Tree)': (["a treasure tracker for an ancient tree", "a magnetic needle for an ancient tree"], "a Deku Tree Compass", 'item'),
'Compass (Dodongos Cavern)': (["a treasure tracker for an immense cavern", "a magnetic needle for an immense cavern"], "a Dodongo's Cavern Compass", 'item'),
'Compass (Jabu Jabus Belly)': (["a treasure tracker for the belly of a deity", "a magnetic needle for the belly of a deity"], "a Jabu Jabu's Belly Compass", 'item'),
'Compass (Forest Temple)': (["a treasure tracker for a deep forest", "a magnetic needle for a deep forest"], "a Forest Temple Compass", 'item'),
'Compass (Fire Temple)': (["a treasure tracker for a high mountain", "a magnetic needle for a high mountain"], "a Fire Temple Compass", 'item'),
'Compass (Water Temple)': (["a treasure tracker for a vast lake", "a magnetic needle for a vast lake"], "a Water Temple Compass", 'item'),
'Compass (Shadow Temple)': (["a treasure tracker for the house of the dead", "a magnetic needle for the house of the dead"], "a Shadow Temple Compass", 'item'),
'Compass (Spirit Temple)': (["a treasure tracker for a goddess of the sand", "a magnetic needle for a goddess of the sand"], "a Spirit Temple Compass", 'item'),
'Compass (Bottom of the Well)': (["a treasure tracker for a shadow's prison", "a magnetic needle for a shadow's prison"], "a Bottom of the Well Compass", 'item'),
'Compass (Ice Cavern)': (["a treasure tracker for a frozen maze", "a magnetic needle for a frozen maze"], "an Ice Cavern Compass", 'item'),
'BossKey': (["a master of unlocking", "a dungeon's master pass"], "a Boss Key", 'item'),
'GanonBossKey': (["a master of unlocking", "a dungeon's master pass"], "a Boss Key", 'item'),
'SmallKey': (["a tool for unlocking", "a dungeon pass", "a lock remover", "a lockpick"], "a Small Key", 'item'),
'HideoutSmallKey': (["a get out of jail free card"], "a Jail Key", 'item'),
'Boss Key (Forest Temple)': (["a master of unlocking for a deep forest", "a master pass for a deep forest"], "the Forest Temple Boss Key", 'item'),
'Boss Key (Fire Temple)': (["a master of unlocking for a high mountain", "a master pass for a high mountain"], "the Fire Temple Boss Key", 'item'),
'Boss Key (Water Temple)': (["a master of unlocking for under a vast lake", "a master pass for under a vast lake"], "the Water Temple Boss Key", 'item'),
'Boss Key (Shadow Temple)': (["a master of unlocking for the house of the dead", "a master pass for the house of the dead"], "the Shadow Temple Boss Key", 'item'),
'Boss Key (Spirit Temple)': (["a master of unlocking for a goddess of the sand", "a master pass for a goddess of the sand"], "the Spirit Temple Boss Key", 'item'),
'Boss Key (Ganons Castle)': (["an master of unlocking", "a floating dungeon's master pass"], "Ganon's Castle Boss Key", 'item'),
'Small Key (Forest Temple)': (["a tool for unlocking a deep forest", "a dungeon pass for a deep forest", "a lock remover for a deep forest", "a lockpick for a deep forest"], "a Forest Temple Small Key", 'item'),
'Small Key (Fire Temple)': (["a tool for unlocking a high mountain", "a dungeon pass for a high mountain", "a lock remover for a high mountain", "a lockpick for a high mountain"], "a Fire Temple Small Key", 'item'),
'Small Key (Water Temple)': (["a tool for unlocking a vast lake", "a dungeon pass for under a vast lake", "a lock remover for under a vast lake", "a lockpick for under a vast lake"], "a Water Temple Small Key", 'item'),
'Small Key (Shadow Temple)': (["a tool for unlocking the house of the dead", "a dungeon pass for the house of the dead", "a lock remover for the house of the dead", "a lockpick for the house of the dead"], "a Shadow Temple Small Key", 'item'),
'Small Key (Spirit Temple)': (["a tool for unlocking a goddess of the sand", "a dungeon pass for a goddess of the sand", "a lock remover for a goddess of the sand", "a lockpick for a goddess of the sand"], "a Spirit Temple Small Key", 'item'),
'Small Key (Bottom of the Well)': (["a tool for unlocking a shadow's prison", "a dungeon pass for a shadow's prison", "a lock remover for a shadow's prison", "a lockpick for a shadow's prison"], "a Bottom of the Well Small Key", 'item'),
'Small Key (Gerudo Training Ground)': (["a tool for unlocking the test of thieves", "a dungeon pass for the test of thieves", "a lock remover for the test of thieves", "a lockpick for the test of thieves"], "a Gerudo Training Ground Small Key", 'item'),
'Small Key (Ganons Castle)': (["a tool for unlocking a conquered citadel", "a dungeon pass for a conquered citadel", "a lock remover for a conquered citadel", "a lockpick for a conquered citadel"], "a Ganon's Castle Small Key", 'item'),
'Small Key (Thieves Hideout)': (["a get out of jail free card"], "a Jail Key", 'item'),
'Small Key Ring (Forest Temple)': (["a toolbox for unlocking a deep forest", "a dungeon season pass for a deep forest", "a jingling ring for a deep forest", "a skeleton key for a deep forest"], "a Forest Temple Small Key Ring", 'item'),
'Small Key Ring (Fire Temple)': (["a toolbox for unlocking a high mountain", "a dungeon season pass for a high mountain", "a jingling ring for a high mountain", "a skeleton key for a high mountain"], "a Fire Temple Small Key Ring", 'item'),
'Small Key Ring (Water Temple)': (["a toolbox for unlocking a vast lake", "a dungeon season pass for under a vast lake", "a jingling ring for under a vast lake", "a skeleton key for under a vast lake"], "a Water Temple Small Key Ring", 'item'),
'Small Key Ring (Shadow Temple)': (["a toolbox for unlocking the house of the dead", "a dungeon season pass for the house of the dead", "a jingling ring for the house of the dead", "a skeleton key for the house of the dead"], "a Shadow Temple Small Key Ring", 'item'),
'Small Key Ring (Spirit Temple)': (["a toolbox for unlocking a goddess of the sand", "a dungeon season pass for a goddess of the sand", "a jingling ring for a goddess of the sand", "a skeleton key for a goddess of the sand"], "a Spirit Temple Small Key Ring", 'item'),
'Small Key Ring (Bottom of the Well)': (["a toolbox for unlocking a shadow's prison", "a dungeon season pass for a shadow's prison", "a jingling ring for a shadow's prison", "a skeleton key for a shadow's prison"], "a Bottom of the Well Small Key Ring", 'item'),
'Small Key Ring (Gerudo Training Ground)': (["a toolbox for unlocking the test of thieves", "a dungeon season pass for the test of thieves", "a jingling ring for the test of thieves", "a skeleton key for the test of thieves"], "a Gerudo Training Ground Small Key Ring", 'item'),
'Small Key Ring (Ganons Castle)': (["a toolbox for unlocking a conquered citadel", "a dungeon season pass for a conquered citadel", "a jingling ring for a conquered citadel", "a skeleton key for a conquered citadel"], "a Ganon's Castle Small Key Ring", 'item'),
'Small Key Ring (Thieves Hideout)': (["a deck of get out of jail free cards"], "a Jail Key Ring", 'item'),
'KeyError': (["something mysterious", "an unknown treasure"], "An Error (Please Report This)", 'item'),
'Arrows (5)': (["a few danger darts", "a few sharp shafts"], "Arrows (5 pieces)", 'item'),
'Arrows (10)': (["some danger darts", "some sharp shafts"], "Arrows (10 pieces)", 'item'),
@ -259,6 +322,7 @@ hintTable = {
'Bombs (20)': (["lots-o-explosives", "plenty of blast balls"], "Bombs (20 pieces)", 'item'),
'Ice Trap': (["a gift from Ganon", "a chilling discovery", "frosty fun"], "an Ice Trap", 'item'),
'Magic Bean': (["a wizardly legume"], "a Magic Bean", 'item'),
'Buy Magic Bean': (["a wizardly legume"], "a Magic Bean", 'item'),
'Magic Bean Pack': (["wizardly legumes"], "Magic Beans", 'item'),
'Bombchus': (["mice bombs", "proximity mice", "wall crawlers", "trail blazers"], "Bombchus", 'item'),
'Bombchus (5)': (["a few mice bombs", "a few proximity mice", "a few wall crawlers", "a few trail blazers"], "Bombchus (5 pieces)", 'item'),
@ -306,12 +370,17 @@ hintTable = {
'ZF GS Hidden Cave': ("a spider high #above the icy waters# holds", None, ['overworld', 'sometimes']),
'Wasteland Chest': (["#deep in the wasteland# is", "beneath #the sands#, flames reveal"], None, ['overworld', 'sometimes']),
'Wasteland GS': ("a #spider in the wasteland# holds", None, ['overworld', 'sometimes']),
'Royal Familys Tomb Chest': (["#flames in the royal tomb# reveal", "the #Composer Brothers hid#"], None, ['overworld', 'sometimes']),
'Graveyard Royal Familys Tomb Chest': (["#flames in the royal tomb# reveal", "the #Composer Brothers hid#"], None, ['overworld', 'sometimes']),
'ZF Bottom Freestanding PoH': ("#under the icy waters# lies", None, ['overworld', 'sometimes']),
'GC Pot Freestanding PoH': ("spinning #Goron pottery# contains", None, ['overworld', 'sometimes']),
'ZD King Zora Thawed': ("a #defrosted dignitary# gifts", "unfreezing #King Zora# grants", ['overworld', 'sometimes']),
'DMC Deku Scrub': ("a single #scrub in the crater# sells", None, ['overworld', 'sometimes']),
'DMC GS Crate': ("a spider under a #crate in the crater# holds", None, ['overworld', 'sometimes']),
'LW Target in Woods': ("shooting a #target in the woods# grants", None, ['overworld', 'sometimes']),
'ZR Frogs in the Rain': ("#frogs in a storm# gift", None, ['overworld', 'sometimes']),
'LH Lab Dive': ("a #diving experiment# is rewarded with", None, ['overworld', 'sometimes']),
'HC Great Fairy Reward': ("the #fairy of fire# holds", "a #fairy outside Hyrule Castle# holds", ['overworld', 'sometimes']),
'OGC Great Fairy Reward': ("the #fairy of strength# holds", "a #fairy outside Ganon's Castle# holds", ['overworld', 'sometimes']),
'Deku Tree MQ After Spinning Log Chest': ("a #temporal stone within a tree# contains", "a #temporal stone within the Deku Tree# contains", ['dungeon', 'sometimes']),
'Deku Tree MQ GS Basement Graves Room': ("a #spider on a ceiling in a tree# holds", "a #spider on a ceiling in the Deku Tree# holds", ['dungeon', 'sometimes']),
@ -324,8 +393,10 @@ hintTable = {
'Fire Temple MQ Chest On Fire': ("the #Flare Dancer atop the volcano# guards a chest containing", "the #Flare Dancer atop the Fire Temple# guards a chest containing", ['dungeon', 'sometimes']),
'Fire Temple MQ GS Skull On Fire': ("a #spider under a block in the volcano# holds", "a #spider under a block in the Fire Temple# holds", ['dungeon', 'sometimes']),
'Water Temple River Chest': ("beyond the #river under the lake# waits", "beyond the #river in the Water Temple# waits", ['dungeon', 'sometimes']),
'Water Temple Central Pillar Chest': ("beneath a #tall tower under a vast lake# lies", "a chest in the #central pillar of Water Temple# contains", ['dungeon', 'sometimes']),
'Water Temple Boss Key Chest': ("dodging #rolling boulders under the lake# leads to", "dodging #rolling boulders in the Water Temple# leads to", ['dungeon', 'sometimes']),
'Water Temple GS Behind Gate': ("a spider behind a #gate under the lake# holds", "a spider behind a #gate in the Water Temple# holds", ['dungeon', 'sometimes']),
'Water Temple MQ Central Pillar Chest': ("beneath a #tall tower under a vast lake# lies", "a chest in the #central pillar of Water Temple# contains", ['dungeon', 'sometimes']),
'Water Temple MQ Freestanding Key': ("hidden in a #box under the lake# lies", "hidden in a #box in the Water Temple# lies", ['dungeon', 'sometimes']),
'Water Temple MQ GS Freestanding Key Area': ("the #locked spider under the lake# holds", "the #locked spider in the Water Temple# holds", ['dungeon', 'sometimes']),
'Water Temple MQ GS Triple Wall Torch': ("a spider behind a #gate under the lake# holds", "a spider behind a #gate in the Water Temple# holds", ['dungeon', 'sometimes']),
@ -333,15 +404,64 @@ hintTable = {
'Gerudo Training Ground MQ Underwater Silver Rupee Chest': (["those who seek #sunken silver rupees# will find", "the #thieves' underwater training# rewards"], None, ['dungeon', 'sometimes']),
'Gerudo Training Ground Maze Path Final Chest': ("the final prize of #the thieves' training# is", None, ['dungeon', 'sometimes']),
'Gerudo Training Ground MQ Ice Arrows Chest': ("the final prize of #the thieves' training# is", None, ['dungeon', 'sometimes']),
'Bottom of the Well Lens of Truth Chest': (["the well's #grasping ghoul# hides", "a #nether dweller in the well# holds"], "#Dead Hand in the well# holds", ['dungeon', 'sometimes']),
'Bottom of the Well MQ Compass Chest': (["the well's #grasping ghoul# hides", "a #nether dweller in the well# holds"], "#Dead Hand in the well# holds", ['dungeon', 'sometimes']),
'Spirit Temple Silver Gauntlets Chest': ("the treasure #sought by Nabooru# is", "upon the #Colossus's right hand# is", ['dungeon', 'sometimes']),
'Spirit Temple Mirror Shield Chest': ("upon the #Colossus's left hand# is", None, ['dungeon', 'sometimes']),
'Spirit Temple MQ Child Hammer Switch Chest': ("a #temporal paradox in the Colossus# yields", "a #temporal paradox in the Spirit Temple# yields", ['dungeon', 'sometimes']),
'Spirit Temple MQ Symphony Room Chest': ("a #symphony in the Colossus# yields", "a #symphony in the Spirit Temple# yields", ['dungeon', 'sometimes']),
'Spirit Temple MQ GS Symphony Room': ("a #spider's symphony in the Colossus# yields", "a #spider's symphony in the Spirit Temple# yields", ['dungeon', 'sometimes']),
'Shadow Temple Invisible Floormaster Chest': ("shadows in an #invisible maze# guard", None, ['dungeon', 'sometimes']),
'Shadow Temple Freestanding Key': ("a #burning skull in the house of the dead# holds", "a #giant pot in the Shadow Temple# holds", ['dungeon', 'sometimes']),
'Shadow Temple MQ Bomb Flower Chest': ("shadows in an #invisible maze# guard", None, ['dungeon', 'sometimes']),
'Shadow Temple MQ Stalfos Room Chest': ("near an #empty pedestal within the house of the dead# lies", "#stalfos in the Shadow Temple# guard", ['dungeon', 'sometimes']),
'Ice Cavern Iron Boots Chest': ("a #monster in a frozen cavern# guards", "the #final treasure of Ice Cavern# is", ['dungeon', 'sometimes']),
'Ice Cavern MQ Iron Boots Chest': ("a #monster in a frozen cavern# guards", "the #final treasure of Ice Cavern# is", ['dungeon', 'sometimes']),
'Ganons Castle Shadow Trial Golden Gauntlets Chest': ("#deep in the test of darkness# lies", "a #like-like in Ganon's Shadow Trial# guards", ['dungeon', 'sometimes']),
'Ganons Castle MQ Shadow Trial Eye Switch Chest': ("#deep in the test of darkness# lies", "shooting an #eye switch in Ganon's Shadow Trial# reveals", ['dungeon', 'sometimes']),
'Deku Theater Rewards': ("the #Skull Mask and Mask of Truth# reward...^", None, 'dual'),
'HF Ocarina of Time Retrieval': ("during her escape, #Princess Zelda# entrusted you with both...^", "the #Ocarina of Time# rewards both...^", 'dual'),
'HF Valley Grotto': ("in a grotto with a #spider and a cow# you will find...^", None, 'dual'),
'Market Bombchu Bowling Rewards': ("at the #Bombchu Bowling Alley#, you will be rewarded with...^", None, 'dual'),
'ZR Frogs Rewards': ("the #Frogs of Zora River# will reward you with...^", None, 'dual'),
'LH Lake Lab Pool': ("inside the #lakeside lab# a person and a spider hold...^", None, 'dual'),
'LH Adult Bean Destination Checks': ("#riding the bean in Lake Hylia# leads to...^", None, 'dual'),
'GV Pieces of Heart Ledges': ("within the #valley#, the crate and waterfall conceal...^", None, 'dual'),
'GF Horseback Archery Rewards': ("the #Gerudo Horseback Archery# rewards...^", None, 'dual'),
'Colossus Nighttime GS': ("#at the Desert Colossus#, skulltulas at night hold...^", None, 'dual'),
'Graveyard Dampe Race Rewards': ("racing #Dampé's ghost# rewards...^", None, 'dual'),
'Graveyard Royal Family Tomb Contents': ("inside the #Royal Family Tomb#, you will find...^", None, 'dual'),
'DMC Child Upper Checks': ("in the #crater, a spider in a crate and a single scrub# guard...^", None, 'dual'),
'Haunted Wasteland Checks': ("deep in the #wasteland a spider and a chest# hold...^", None, 'dual'),
'Deku Tree MQ Basement GS': ("in the back of the #basement of the Great Deku Tree# two spiders hold...^", None, 'dual'),
'Dodongos Cavern Upper Business Scrubs': ("deep in #Dodongo's Cavern a pair of scrubs# sell...^", None, 'dual'),
'Dodongos Cavern MQ Larvae Room': ("amid #larvae in Dodongo's Cavern# a chest and a spider hold...^", None, 'dual'),
'Fire Temple Lower Loop': ("under the #entrance of the Fire Temple# a blocked path leads to...^", None, 'dual'),
'Fire Temple MQ Lower Loop': ("under the #entrance of the Fire Temple# a blocked path leads to...^", None, 'dual'),
'Water Temple River Loop Chests': ("#chests past a shadowy fight# in the Water Temple hold...^", "#chests past Dark Link# in the Water Temple hold...^", 'dual'),
'Water Temple River Checks': ("in the #river in the Water Temple# lies...^", None, 'dual'),
'Water Temple North Basement Checks': ("the #northern basement of the Water Temple# contains...^", None, 'dual'),
'Water Temple MQ North Basement Checks': ("the #northern basement of the Water Temple# contains...^", None, 'dual'),
'Water Temple MQ Lower Checks': ("#a chest and a crate in locked basements# in the Water Temple hold...^", None, 'dual'),
'Spirit Temple Colossus Hands': ("upon the #Colossus's right and left hands# lie...^", None, 'dual'),
'Spirit Temple Child Lower': ("between the #crawl spaces in the Spirit Temple# chests contain...^", None, 'dual'),
'Spirit Temple Child Top': ("on the path to the #right hand of the Spirit Temple# a chest and a spider hold...^", None, 'dual'),
'Spirit Temple Adult Lower': ("past a #silver block in the Spirit Temple# boulders and a melody conceal...^", None, 'dual'),
'Spirit Temple MQ Child Top': ("on the path to the #right hand of the Spirit Temple# a chest and a spider hold respectively...^", None, 'dual'),
'Spirit Temple MQ Symphony Room': ("#the symphony room# in the Spirit Temple protects...^", None, 'dual'),
'Spirit Temple MQ Throne Room GS': ("in the #nine thrones room# of the Spirit Temple spiders hold...^", None, 'dual'),
'Shadow Temple Invisible Blades Chests': ("an #invisible spinning blade# in the Shadow Temple guards...^", None, 'dual'),
'Shadow Temple Single Pot Room': ("a room containing #a single skull-shaped pot# holds...^", "a room containing a #large pot in the Shadow Temple# holds...^", 'dual'),
'Shadow Temple Spike Walls Room': ("#wooden walls# in the Shadow Temple hide...^", None, 'dual'),
'Shadow Temple MQ Upper Checks': ("#before the Truth Spinner gap# in the Shadow Temple locked chests contain...^", None, 'dual'),
'Shadow Temple MQ Invisible Blades Chests': ("an #invisible spinning blade# in the Shadow Temple guards...^", None, 'dual'),
'Shadow Temple MQ Spike Walls Room': ("#wooden walls# in the Shadow Temple hide...^", None, 'dual'),
'Bottom of the Well Inner Rooms GS': ("in the #central rooms of the well# spiders hold...^", None, 'dual'),
'Bottom of the Well Dead Hand Room': ("#Dead Hand in the well# guards...^", None, 'dual'),
'Bottom of the Well MQ Dead Hand Room': ("#Dead Hand in the well# guards...^", None, 'dual'),
'Bottom of the Well MQ Basement': ("in the #depths of the well# a spider and a chest hold...^", None, 'dual'),
'Ice Cavern Final Room': ("the #final treasures of Ice Cavern# are...^", None, 'dual'),
'Ice Cavern MQ Final Room': ("the #final treasures of Ice Cavern# are...^", None, 'dual'),
'Ganons Castle Spirit Trial Chests': ("#within the Spirit Trial#, chests contain...^", None, 'dual'),
'KF Kokiri Sword Chest': ("the #hidden treasure of the Kokiri# is", None, 'exclude'),
'KF Midos Top Left Chest': ("the #leader of the Kokiri# hides", "#inside Mido's house# is", 'exclude'),
@ -353,7 +473,7 @@ hintTable = {
'GC Maze Right Chest': ("in #Goron City# explosives unlock", None, 'exclude'),
'GC Maze Center Chest': ("in #Goron City# explosives unlock", None, 'exclude'),
'ZD Chest': ("fire #beyond a waterfall# reveals", None, 'exclude'),
'Graveyard Hookshot Chest': ("a chest hidden by a #speedy spectre# holds", "#dead Dampé's first prize# is", 'exclude'),
'Graveyard Dampe Race Hookshot Chest': ("a chest hidden by a #speedy spectre# holds", "#dead Dampé's first prize# is", 'exclude'),
'GF Chest': ("on a #rooftop in the desert# lies", None, 'exclude'),
'Kak Redead Grotto Chest': ("#zombies beneath the earth# guard", None, 'exclude'),
'SFM Wolfos Grotto Chest': ("#wolves beneath the earth# guard", None, 'exclude'),
@ -370,11 +490,9 @@ hintTable = {
'ToT Light Arrows Cutscene': ("the #final gift of a princess# is", None, 'exclude'),
'LW Gift from Saria': (["a #potato hoarder# holds", "a rooty tooty #flutey cutey# gifts"], "#Saria's Gift# is", 'exclude'),
'ZF Great Fairy Reward': ("the #fairy of winds# holds", None, 'exclude'),
'HC Great Fairy Reward': ("the #fairy of fire# holds", None, 'exclude'),
'Colossus Great Fairy Reward': ("the #fairy of love# holds", None, 'exclude'),
'DMT Great Fairy Reward': ("a #magical fairy# gifts", None, 'exclude'),
'DMC Great Fairy Reward': ("a #magical fairy# gifts", None, 'exclude'),
'OGC Great Fairy Reward': ("the #fairy of strength# holds", None, 'exclude'),
'Song from Impa': ("#deep in a castle#, Impa teaches", None, 'exclude'),
'Song from Malon': ("#a farm girl# sings", None, 'exclude'),
@ -386,7 +504,6 @@ hintTable = {
'ZD Diving Minigame': ("an #unsustainable business model# gifts", "those who #dive for Zora rupees# will find", 'exclude'),
'LH Child Fishing': ("#fishing in youth# bestows", None, 'exclude'),
'LH Adult Fishing': ("#fishing in maturity# bestows", None, 'exclude'),
'LH Lab Dive': ("a #diving experiment# is rewarded with", None, 'exclude'),
'GC Rolling Goron as Adult': ("#comforting yourself# provides", "#reassuring a young Goron# is rewarded with", 'exclude'),
'Market Bombchu Bowling First Prize': ("the #first explosive prize# is", None, 'exclude'),
'Market Bombchu Bowling Second Prize': ("the #second explosive prize# is", None, 'exclude'),
@ -395,17 +512,16 @@ hintTable = {
'Kak 10 Gold Skulltula Reward': (["#10 bug badges# rewards", "#10 spider souls# yields", "#10 auriferous arachnids# lead to"], "slaying #10 Gold Skulltulas# reveals", 'exclude'),
'Kak Man on Roof': ("a #rooftop wanderer# holds", None, 'exclude'),
'ZR Magic Bean Salesman': ("a seller of #colorful crops# has", "a #bean seller# offers", 'exclude'),
'ZR Frogs in the Rain': ("#frogs in a storm# gift", None, 'exclude'),
'GF HBA 1000 Points': ("scoring 1000 in #horseback archery# grants", None, 'exclude'),
'Market Shooting Gallery Reward': ("#shooting in youth# grants", None, 'exclude'),
'Kak Shooting Gallery Reward': ("#shooting in maturity# grants", None, 'exclude'),
'LW Target in Woods': ("shooting a #target in the woods# grants", None, 'exclude'),
'Kak Anju as Adult': ("a #chicken caretaker# offers adults", None, 'exclude'),
'LLR Talons Chickens': ("#finding Super Cuccos# is rewarded with", None, 'exclude'),
'GC Rolling Goron as Child': ("the prize offered by a #large rolling Goron# is", None, 'exclude'),
'LH Underwater Item': ("the #sunken treasure in a lake# is", None, 'exclude'),
'Hideout Gerudo Membership Card': ("#rescuing captured carpenters# is rewarded with", None, 'exclude'),
'Wasteland Bombchu Salesman': ("a #carpet guru# sells", None, 'exclude'),
'GC Medigoron': ("#Medigoron# sells", None, 'exclude'),
'Kak Impas House Freestanding PoH': ("#imprisoned in a house# lies", None, 'exclude'),
'HF Tektite Grotto Freestanding PoH': ("#deep underwater in a hole# is", None, 'exclude'),
@ -424,10 +540,16 @@ hintTable = {
'DMT Freestanding PoH': ("above a #mountain cavern entrance# is", None, 'exclude'),
'DMC Wall Freestanding PoH': ("nestled in a #volcanic wall# is", None, 'exclude'),
'DMC Volcano Freestanding PoH': ("obscured by #volcanic ash# is", None, 'exclude'),
'Hideout Jail Guard (1 Torch)': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout Jail Guard (2 Torches)': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout Jail Guard (3 Torches)': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout Jail Guard (4 Torches)': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout 1 Torch Jail Gerudo Key': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout 2 Torches Jail Gerudo Key': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout 3 Torches Jail Gerudo Key': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'Hideout 4 Torches Jail Gerudo Key': ("#defeating Gerudo guards# reveals", None, 'exclude'),
'ZR Frogs Zeldas Lullaby': ("after hearing #Zelda's Lullaby, frogs gift#", None, 'exclude'),
'ZR Frogs Eponas Song': ("after hearing #Epona's Song, frogs gift#", None, 'exclude'),
'ZR Frogs Sarias Song': ("after hearing #Saria's Song, frogs gift#", None, 'exclude'),
'ZR Frogs Suns Song': ("after hearing the #Sun's Song, frogs gift#", None, 'exclude'),
'ZR Frogs Song of Time': ("after hearing the #Song of Time, frogs gift#", None, 'exclude'),
'Deku Tree Map Chest': ("in the #center of the Deku Tree# lies", None, 'exclude'),
'Deku Tree Slingshot Chest': ("the #treasure guarded by a scrub# in the Deku Tree is", None, 'exclude'),
@ -480,13 +602,14 @@ hintTable = {
'Forest Temple Raised Island Courtyard Chest': ("a #chest on a small island# in the Forest Temple holds", None, 'exclude'),
'Forest Temple Falling Ceiling Room Chest': ("beneath a #checkerboard falling ceiling# lies", None, 'exclude'),
'Forest Temple Eye Switch Chest': ("a #sharp eye# will spot", "#blocks of stone# in the Forest Temple surround", 'exclude'),
'Forest Temple Boss Key Chest': ("a #turned trunk# contains", None, 'exclude'),
'Forest Temple Floormaster Chest': ("deep in the forest #shadows guard a chest# containing", None, 'exclude'),
'Forest Temple Bow Chest': ("an #army of the dead# guards", "#Stalfos deep in the Forest Temple# guard", 'exclude'),
'Forest Temple Red Poe Chest': ("#Joelle# guards", "a #red ghost# guards", 'exclude'),
'Forest Temple Blue Poe Chest': ("#Beth# guards", "a #blue ghost# guards", 'exclude'),
'Forest Temple Basement Chest': ("#revolving walls# in the Forest Temple conceal", None, 'exclude'),
'Forest Temple Boss Key Chest': ("a #turned trunk# contains", "a #sideways chest in the Forest Temple# hides", 'exclude'),
'Forest Temple MQ Boss Key Chest': ("a #turned trunk# contains", "a #sideways chest in the Forest Temple# hides", 'exclude'),
'Forest Temple MQ First Room Chest': ("a #tree in the Forest Temple# supports", None, 'exclude'),
'Forest Temple MQ Wolfos Chest': ("#defeating enemies beneath a falling ceiling# in Forest Temple yields", None, 'exclude'),
'Forest Temple MQ Bow Chest': ("an #army of the dead# guards", "#Stalfos deep in the Forest Temple# guard", 'exclude'),
@ -498,7 +621,6 @@ hintTable = {
'Forest Temple MQ Falling Ceiling Room Chest': ("beneath a #checkerboard falling ceiling# lies", None, 'exclude'),
'Forest Temple MQ Basement Chest': ("#revolving walls# in the Forest Temple conceal", None, 'exclude'),
'Forest Temple MQ Redead Chest': ("deep in the forest #undead guard a chest# containing", None, 'exclude'),
'Forest Temple MQ Boss Key Chest': ("a #turned trunk# contains", None, 'exclude'),
'Fire Temple Near Boss Chest': ("#near a dragon# is", None, 'exclude'),
'Fire Temple Flare Dancer Chest': ("the #Flare Dancer behind a totem# guards", None, 'exclude'),
@ -530,11 +652,9 @@ hintTable = {
'Water Temple Torches Chest': ("#fire in the Water Temple# reveals", None, 'exclude'),
'Water Temple Dragon Chest': ("a #serpent's prize# in the Water Temple is", None, 'exclude'),
'Water Temple Central Bow Target Chest': ("#blinding an eye# in the Water Temple leads to", None, 'exclude'),
'Water Temple Central Pillar Chest': ("in the #depths of the Water Temple# lies", None, 'exclude'),
'Water Temple Cracked Wall Chest': ("#through a crack# in the Water Temple is", None, 'exclude'),
'Water Temple Longshot Chest': (["#facing yourself# reveals", "a #dark reflection# of yourself guards"], "#Dark Link# guards", 'exclude'),
'Water Temple MQ Central Pillar Chest': ("in the #depths of the Water Temple# lies", None, 'exclude'),
'Water Temple MQ Boss Key Chest': ("fire in the Water Temple unlocks a #vast gate# revealing a chest with", None, 'exclude'),
'Water Temple MQ Longshot Chest': ("#through a crack# in the Water Temple is", None, 'exclude'),
'Water Temple MQ Compass Chest': ("#fire in the Water Temple# reveals", None, 'exclude'),
@ -591,8 +711,8 @@ hintTable = {
'Shadow Temple After Wind Enemy Chest': ("#mummies guarding a ferry# hide", None, 'exclude'),
'Shadow Temple After Wind Hidden Chest': ("#mummies guarding a ferry# hide", None, 'exclude'),
'Shadow Temple Spike Walls Left Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'),
'Shadow Temple Invisible Floormaster Chest': ("shadows in an #invisible maze# guard", None, 'exclude'),
'Shadow Temple Boss Key Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'),
'Shadow Temple Freestanding Key': ("#inside a burning skull# lies", None, 'exclude'),
'Shadow Temple MQ Compass Chest': ("the #Eye of Truth# pierces a hall of faces to reveal", None, 'exclude'),
'Shadow Temple MQ Hover Boots Chest': ("#Dead Hand in the Shadow Temple# holds", None, 'exclude'),
@ -605,7 +725,6 @@ hintTable = {
'Shadow Temple MQ Invisible Spikes Chest': ("the #dead roam among invisible spikes# guarding", None, 'exclude'),
'Shadow Temple MQ Boss Key Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'),
'Shadow Temple MQ Spike Walls Left Chest': ("#walls consumed by a ball of fire# reveal", None, 'exclude'),
'Shadow Temple MQ Stalfos Room Chest': ("near an #empty pedestal# within the Shadow Temple lies", None, 'exclude'),
'Shadow Temple MQ Invisible Blades Invisible Chest': ("#invisible blades# guard", None, 'exclude'),
'Shadow Temple MQ Invisible Blades Visible Chest': ("#invisible blades# guard", None, 'exclude'),
'Shadow Temple MQ Wind Hint Chest': ("an #invisible chest guarded by the dead# holds", None, 'exclude'),
@ -627,18 +746,18 @@ hintTable = {
'Bottom of the Well Fire Keese Chest': ("#perilous pits# in the well guard the path to", None, 'exclude'),
'Bottom of the Well Like Like Chest': ("#locked in a cage# in the well lies", None, 'exclude'),
'Bottom of the Well Freestanding Key': ("#inside a coffin# hides", None, 'exclude'),
'Bottom of the Well Lens of Truth Chest': (["the well's #grasping ghoul# hides", "a #nether dweller in the well# holds"], "#Dead Hand in the well# holds", 'exclude'),
'Bottom of the Well MQ Compass Chest': (["the well's #grasping ghoul# hides", "a #nether dweller in the well# holds"], "#Dead Hand in the well# holds", 'exclude'),
'Bottom of the Well MQ Map Chest': ("a #royal melody in the well# uncovers", None, 'exclude'),
'Bottom of the Well MQ Lens of Truth Chest': ("an #army of the dead# in the well guards", None, 'exclude'),
'Bottom of the Well MQ Dead Hand Freestanding Key': ("#Dead Hand's explosive secret# is", None, 'exclude'),
'Bottom of the Well MQ East Inner Room Freestanding Key': ("an #invisible path in the well# leads to", None, 'exclude'),
'Ice Cavern Map Chest': ("#winds of ice# surround", None, 'exclude'),
'Ice Cavern Map Chest': ("#winds of ice# surround", "a chest #atop a pillar of ice# contains", 'exclude'),
'Ice Cavern Compass Chest': ("a #wall of ice# protects", None, 'exclude'),
'Ice Cavern Iron Boots Chest': ("a #monster in a frozen cavern# guards", None, 'exclude'),
'Ice Cavern Freestanding PoH': ("a #wall of ice# protects", None, 'exclude'),
'Ice Cavern MQ Iron Boots Chest': ("a #monster in a frozen cavern# guards", None, 'exclude'),
'Ice Cavern MQ Compass Chest': ("#winds of ice# surround", None, 'exclude'),
'Ice Cavern MQ Map Chest': ("a #wall of ice# protects", None, 'exclude'),
'Ice Cavern MQ Freestanding PoH': ("#winds of ice# surround", None, 'exclude'),
@ -686,7 +805,6 @@ hintTable = {
'Ganons Castle Water Trial Left Chest': ("the #test of the seas# holds", None, 'exclude'),
'Ganons Castle Water Trial Right Chest': ("the #test of the seas# holds", None, 'exclude'),
'Ganons Castle Shadow Trial Front Chest': ("#music in the test of darkness# unveils", None, 'exclude'),
'Ganons Castle Shadow Trial Golden Gauntlets Chest': ("#light in the test of darkness# unveils", None, 'exclude'),
'Ganons Castle Spirit Trial Crystal Switch Chest': ("the #test of the sands# holds", None, 'exclude'),
'Ganons Castle Spirit Trial Invisible Chest': ("the #test of the sands# holds", None, 'exclude'),
'Ganons Castle Light Trial First Left Chest': ("the #test of radiance# holds", None, 'exclude'),
@ -703,7 +821,6 @@ hintTable = {
'Ganons Castle MQ Forest Trial Frozen Eye Switch Chest': ("the #test of the wilds# holds", None, 'exclude'),
'Ganons Castle MQ Light Trial Lullaby Chest': ("#music in the test of radiance# reveals", None, 'exclude'),
'Ganons Castle MQ Shadow Trial Bomb Flower Chest': ("the #test of darkness# holds", None, 'exclude'),
'Ganons Castle MQ Shadow Trial Eye Switch Chest': ("the #test of darkness# holds", None, 'exclude'),
'Ganons Castle MQ Spirit Trial Golden Gauntlets Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'),
'Ganons Castle MQ Spirit Trial Sun Back Right Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'),
'Ganons Castle MQ Spirit Trial Sun Back Left Chest': ("#reflected light in the test of the sands# reveals", None, 'exclude'),
@ -721,6 +838,16 @@ hintTable = {
'Spirit Temple Twinrova Heart': ("the #Sorceress Sisters# hold", "#Twinrova# holds", 'exclude'),
'Shadow Temple Bongo Bongo Heart': ("the #Phantom Shadow Beast# holds", "#Bongo Bongo# holds", 'exclude'),
'Queen Gohma': ("the #Parasitic Armored Arachnid# holds", "#Queen Gohma# holds", 'exclude'),
'King Dodongo': ("the #Infernal Dinosaur# holds", "#King Dodongo# holds", 'exclude'),
'Barinade': ("the #Bio-Electric Anemone# holds", "#Barinade# holds", 'exclude'),
'Phantom Ganon': ("the #Evil Spirit from Beyond# holds", "#Phantom Ganon# holds", 'exclude'),
'Volvagia': ("the #Subterranean Lava Dragon# holds", "#Volvagia# holds", 'exclude'),
'Morpha': ("the #Giant Aquatic Amoeba# holds", "#Morpha# holds", 'exclude'),
'Bongo Bongo': ("the #Sorceress Sisters# hold", "#Twinrova# holds", 'exclude'),
'Twinrova': ("the #Phantom Shadow Beast# holds", "#Bongo Bongo# holds", 'exclude'),
'Links Pocket': ("#@'s pocket# holds", "@ already has", 'exclude'),
'Deku Tree GS Basement Back Room': ("a #spider deep within the Deku Tree# hides", None, 'exclude'),
'Deku Tree GS Basement Gate': ("a #web protects a spider# within the Deku Tree holding", None, 'exclude'),
'Deku Tree GS Basement Vines': ("a #web protects a spider# within the Deku Tree holding", None, 'exclude'),
@ -768,10 +895,10 @@ hintTable = {
'Fire Temple GS Scarecrow Top': ("a #spider-friendly scarecrow# atop a volcano hides", "a #spider-friendly scarecrow# atop the Fire Temple hides", 'exclude'),
'Fire Temple GS Scarecrow Climb': ("a #spider-friendly scarecrow# atop a volcano hides", "a #spider-friendly scarecrow# atop the Fire Temple hides", 'exclude'),
'Fire Temple MQ GS Above Fire Wall Maze': ("a #spider above a fiery maze# holds", None, 'exclude'),
'Fire Temple MQ GS Fire Wall Maze Center': ("a #spider within a fiery maze# holds", None, 'exclude'),
'Fire Temple MQ GS Above Flame Maze': ("a #spider above a fiery maze# holds", None, 'exclude'),
'Fire Temple MQ GS Flame Maze Center': ("a #spider within a fiery maze# holds", None, 'exclude'),
'Fire Temple MQ GS Big Lava Room Open Door': ("a #Goron trapped near lava# befriended a spider with", None, 'exclude'),
'Fire Temple MQ GS Fire Wall Maze Side Room': ("a #spider beside a fiery maze# holds", None, 'exclude'),
'Fire Temple MQ GS Flame Maze Side Room': ("a #spider beside a fiery maze# holds", None, 'exclude'),
'Water Temple GS Falling Platform Room': ("a #spider over a waterfall# in the Water Temple holds", None, 'exclude'),
'Water Temple GS Central Pillar': ("a #spider in the center of the Water Temple# holds", None, 'exclude'),
@ -796,7 +923,7 @@ hintTable = {
'Shadow Temple GS Single Giant Pot': ("#beyond a burning skull# lies a spider with", None, 'exclude'),
'Shadow Temple GS Falling Spikes Room': ("a #spider beyond falling spikes# holds", None, 'exclude'),
'Shadow Temple GS Triple Giant Pot': ("#beyond three burning skulls# lies a spider with", None, 'exclude'),
'Shadow Temple GS Like Like Room': ("a spider guarded by #invisible blades# holds", None, 'exclude'),
'Shadow Temple GS Invisible Blades Room': ("a spider guarded by #invisible blades# holds", None, 'exclude'),
'Shadow Temple GS Near Ship': ("a spider near a #docked ship# hoards", None, 'exclude'),
'Shadow Temple MQ GS Falling Spikes Room': ("a #spider beyond falling spikes# holds", None, 'exclude'),
@ -853,7 +980,7 @@ hintTable = {
'Kak GS House Under Construction': ("night in the past reveals a #spider in a town# holding", None, 'exclude'),
'Kak GS Skulltula House': ("night in the past reveals a #spider in a town# holding", None, 'exclude'),
'Kak GS Guards House': ("night in the past reveals a #spider in a town# holding", None, 'exclude'),
'Kak GS Near Gate Guard': ("night in the past reveals a #spider in a town# holding", None, 'exclude'),
'Kak GS Tree': ("night in the past reveals a #spider in a town# holding", None, 'exclude'),
'Kak GS Watchtower': ("night in the past reveals a #spider in a town# holding", None, 'exclude'),
'Kak GS Above Impas House': ("night in the future reveals a #spider in a town# holding", None, 'exclude'),
@ -1030,7 +1157,7 @@ hintTable = {
'Desert Colossus -> Colossus Grotto': ("lifting a #rock in the desert# reveals", None, 'entrance'),
'GV Grotto Ledge -> GV Octorok Grotto': ("a rock on #a ledge in the valley# hides", None, 'entrance'),
'GC Grotto Platform -> GC Grotto': ("a #pool of lava# in Goron City blocks the way to", None, 'entrance'),
'Gerudo Fortress -> GF Storms Grotto': ("a #storm within Gerudo's Fortress# reveals", None, 'entrance'),
'GF Entrances Behind Crates -> GF Storms Grotto': ("a #storm within Gerudo's Fortress# reveals", None, 'entrance'),
'Zoras Domain -> ZD Storms Grotto': ("a #storm within Zora's Domain# reveals", None, 'entrance'),
'Hyrule Castle Grounds -> HC Storms Grotto': ("a #storm near the castle# reveals", None, 'entrance'),
'GV Fortress Side -> GV Storms Grotto': ("a #storm in the valley# reveals", None, 'entrance'),
@ -1044,6 +1171,8 @@ hintTable = {
'Zoras Fountain -> Jabu Jabus Belly Beginning': ("inside #Jabu Jabu#, one can find", None, 'entrance'),
'Kakariko Village -> Bottom of the Well': ("a #village well# leads to", None, 'entrance'),
'Ganons Castle Grounds -> Ganons Castle Lobby': ("the #rainbow bridge# leads to", None, 'entrance'),
'KF Links House': ("Link's House", None, 'region'),
'Temple of Time': ("the #Temple of Time#", None, 'region'),
'KF Midos House': ("Mido's house", None, 'region'),
@ -1087,7 +1216,7 @@ hintTable = {
'ZF Great Fairy Fountain': ("a #Great Fairy Fountain#", None, 'region'),
'Graveyard Shield Grave': ("a #grave with a free chest#", None, 'region'),
'Graveyard Heart Piece Grave': ("a chest spawned by #Sun's Song#", None, 'region'),
'Royal Familys Tomb': ("the #Royal Family's Tomb#", None, 'region'),
'Graveyard Royal Familys Tomb': ("the #Royal Family's Tomb#", None, 'region'),
'Graveyard Dampes Grave': ("Dampé's Grave", None, 'region'),
'DMT Cow Grotto': ("a solitary #Cow#", None, 'region'),
'HC Storms Grotto': ("a sandy grotto with #fragile walls#", None, 'region'),
@ -1123,49 +1252,50 @@ hintTable = {
'ZD Storms Grotto': ("a small #Fairy Fountain#", None, 'region'),
'GF Storms Grotto': ("a small #Fairy Fountain#", None, 'region'),
# '1001': ("Ganondorf 2022!", None, 'junk'),
'1002': ("They say that monarchy is a terrible system of governance.", None, 'junk'),
'1003': ("They say that Zelda is a poor leader.", None, 'junk'),
# Junk hints must satisfy all of the following conditions:
# - They aren't inappropriate.
# - They aren't absurdly long copy pastas.
# - They aren't quotes or references that are simply not funny when out-of-context.
# To elaborate on this last point: junk hints need to be able to be understood
# by everyone, and not just those who get the obscure references.
# Zelda references are considered fair game.
# First generation junk hints
'1002': ("${12 68 79}They say that monarchy is a terrible system of governance.", None, 'junk'), # sfx: Zelda gasp
'1003': ("${12 68 79}They say that Zelda is a poor leader.", None, 'junk'), # sfx: Zelda gasp
'1004': ("These hints can be quite useful. This is an exception.", None, 'junk'),
'1006': ("They say that all the Zora drowned in Wind Waker.", None, 'junk'),
'1008': ("'Member when Ganon was a blue pig?^I 'member.", None, 'junk'),
'1008': ("Remember when Ganon was a blue pig?^I remember.", None, 'junk'), # ref: A Link to the Past
'1009': ("One who does not have Triforce can't go in.", None, 'junk'),
'1010': ("Save your future, end the Happy Mask Salesman.", None, 'junk'),
'1012': ("I'm stoned. Get it?", None, 'junk'),
'1013': ("Hoot! Hoot! Would you like me to repeat that?", None, 'junk'),
'1014': ("Gorons are stupid. They eat rocks.", None, 'junk'),
'1013': ("Hoot! Hoot! Would you like me to repeat that?", None, 'junk'), # ref: Kaepora Gaebora (the owl)
'1014': ("Gorons are stupid. They eat rocks. Except, apparently, the big rock blocking Dodongo's Cavern.", None, 'junk'),
'1015': ("They say that Lon Lon Ranch prospered under Ingo.", None, 'junk'),
'1016': ("The single rupee is a unique item.", None, 'junk'),
'1017': ("Without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!", None, 'junk'),
'1018': ("Use bombs wisely.", None, 'junk'),
'1021': ("I found you, faker!", None, 'junk'),
'1022': ("You're comparing yourself to me?^Ha! You're not even good enough to be my fake.", None, 'junk'),
'1023': ("I'll make you eat those words.", None, 'junk'),
'1022': ("You're comparing yourself to me?^Ha! You're not even good enough to be my fake.", None, 'junk'), # ref: SA2
'1024': ("What happened to Sheik?", None, 'junk'),
# '1025': ("L2P @.", None, 'junk'),
'1026': ("I've heard Sploosh Kaboom is a tricky game.", None, 'junk'),
'1027': ("I'm Lonk from Pennsylvania.", None, 'junk'),
'1026': ("I've heard Sploosh Kaboom is a tricky game.", None, 'junk'), # ref: Wind Waker
'1028': ("I bet you'd like to have more bombs.", None, 'junk'),
'1029': ("When all else fails, use Fire.", None, 'junk'),
# '1030': ("Here's a hint, @. Don't be bad.", None, 'junk'),
'1031': ("Game Over. Return of Ganon.", None, 'junk'),
'1031': ("Game Over. Return of Ganon.", None, 'junk'), # ref: Zelda II
'1032': ("May the way of the Hero lead to the Triforce.", None, 'junk'),
'1033': ("Can't find an item? Scan an Amiibo.", None, 'junk'),
'1034': ("They say this game has just a few glitches.", None, 'junk'),
'1035': ("BRRING BRRING This is Ulrira. Wrong number?", None, 'junk'),
'1036': ("Tingle Tingle Kooloo Limpah", None, 'junk'),
'1037': ("L is real 2041", None, 'junk'),
'1035': ("BRRING BRRING This is Ulrira. Wrong number?", None, 'junk'), # ref: Link's Awakening
'1036': ("Tingle Tingle Kooloo Limpah", None, 'junk'), # ref: Majora's Mask
'1038': ("They say that Ganondorf will appear in the next Mario Tennis.", None, 'junk'),
'1039': ("Medigoron sells the earliest Breath of the Wild demo.", None, 'junk'),
'1040': ("There's a reason why I am special inquisitor!", None, 'junk'),
'1041': ("You were almost a @ sandwich.", None, 'junk'),
'1042': ("I'm a helpful hint Gossip Stone!^See, I'm helping.", None, 'junk'),
'1043': ("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, princess Zelda.", None, 'junk'),
'1044': ("They say all toasters toast toast.", None, 'junk'),
'1045': ("They say that Okami is the best Zelda game.", None, 'junk'),
'1043': ("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, princess Zelda.", None, 'junk'), # ref: Super Mario 64
'1044': ("They say all toasters toast toast.", None, 'junk'), # ref: Hotel Mario
'1045': ("They say that Okami is the best Zelda game.", None, 'junk'), # ref: people often say that Okami feels and plays like a Zelda game
'1046': ("They say that quest guidance can be found at a talking rock.", None, 'junk'),
# '1047': ("They say that the final item you're looking for can be found somewhere in Hyrule.", None, 'junk'),
'1048': ("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.", None, 'junk'),
'1048': ("${12 68 7a}Mweep${07 04 51}", None, 'junk'), # Mweep
'1049': ("They say that Barinade fears Deku Nuts.", None, 'junk'),
'1050': ("They say that Flare Dancers do not fear Goron-crafted blades.", None, 'junk'),
'1051': ("They say that Morpha is easily trapped in a corner.", None, 'junk'),
@ -1174,63 +1304,220 @@ hintTable = {
'1054': ("They say that bombing the hole Volvagia last flew into can be rewarding.", None, 'junk'),
'1055': ("They say that invisible ghosts can be exposed with Deku Nuts.", None, 'junk'),
'1056': ("They say that the real Phantom Ganon is bright and loud.", None, 'junk'),
'1057': ("They say that walking backwards is very fast.", None, 'junk'),
'1057': ("They say that the fastest way forward is walking backwards.", None, 'junk'),
'1058': ("They say that leaping above the Market entrance enriches most children.", None, 'junk'),
'1059': ("They say that looking into darkness may find darkness looking back into you.", None, 'junk'),
'1059': ("They say that looking into darkness may find darkness looking back into you.", None, 'junk'), # ref: Nietzsche
'1060': ("You found a spiritual Stone! By which I mean, I worship Nayru.", None, 'junk'),
'1061': ("They say that the stick is mightier than the sword.", None, 'junk'),
'1062': ("Open your eyes.^Open your eyes.^Wake up, @.", None, 'junk'),
'1061': ("A broken stick is just as good as a Master Sword. Who knew?", None, 'junk'),
'1062': ("Open your eyes.^Open your eyes.^Wake up, @.", None, 'junk'), # ref: Breath of the Wild
'1063': ("They say that arbitrary code execution leads to the credits sequence.", None, 'junk'),
'1064': ("They say that Twinrova always casts the same spell the first three times.", None, 'junk'),
# '1065': ("They say that the Development branch may be unstable.", None, 'junk'),
'1066': ("You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!", None, 'junk'),
'1066': ("You're playing a Randomizer. I'm randomized!^${12 48 31}Here's a random number: #4#.&Enjoy your Randomizer!", None, 'junk'), # ref: xkcd comic / sfx: get small item from chest
'1067': ("They say Ganondorf's bolts can be reflected with glass or steel.", None, 'junk'),
'1068': ("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, boomerangs...^...rods, shovels, iron balls, angry bees...", None, 'junk'),
'1068': ("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, boomerangs...^...rods, shovels, iron balls, angry bees...", None, 'junk'), # ref: various Zelda games
'1069': ("They say that you're wasting time reading this hint, but I disagree. Talk to me again!", None, 'junk'),
'1070': ("They say Ganondorf knows where to find the instrument of his doom.", None, 'junk'),
'1071': ("I heard @ is pretty good at Zelda.", None, 'junk'),
'Deku Tree': ("an ancient tree", "Deku Tree", 'dungeonName'),
# Second generation junk hints
'1072': ("Fingers-Mazda, the first thief in the world, stole fire from the gods.^But he was unable to fence it.&It was too hot.&He got really burned on that deal.", None, 'junk'), # ref: Discworld
'1073': ("Boing-oing!^There are times in life when one should seek the help of others...^Thus, when standing alone fails to help, stand together.", None, 'junk'), # ref: Gossip Stone in Phantom Hourglass
'1074': ("They say that if you don't use your slingshot at all when you play the slingshot minigame, the owner gets upset with you.", None, 'junk'),
'1075': ("Hey! Wait! Don't go out! It's unsafe!^Wild Pokémon live in tall grass!^You need your own Pokémon for your protection.", None, 'junk'), # ref: Pokémon
'1076': ("They say it's 106 miles to Hyrule Castle, we have half a bar of magic, it's dark, and we're wearing sunglasses.", None, 'junk'), # ref: Blues Brothers
'1078': ("It would be a shame if something... unfortunate... were to happen to you.^Have you considered saving lately?", None, 'junk'), # ref: meme
'1079': ("They say that something wonderful happens when playing the Song of Storms after planting a magic bean.", None, 'junk'),
'1080': ("Long time watcher, first time player. Greetings from Termina. Incentive goes to Randobot's choice.", None, 'junk'), # ref: GDQ meme
'1081': ("No matter what happens...Do not give up, do not complain, and do NOT stay up all night playing!", None, 'junk'), # ref: Wind Waker
'1082': ("That's a nice wall you got there. Would be a shame if I just... clipped right through that.", None, 'junk'),
'1083': ("Ganondorf used to be an adventurer like me, but then he took a light arrow to the knee.", None, 'junk'), # ref: Skyrim
'1084': ("They say that the easiest way to kill Peahats is using Din's Fire while they're grounded.", None, 'junk'),
'1085': ("They say that the castle guards' routes have major security vulnerabilities.", None, 'junk'),
'1086': ("They say that Epona is an exceptional horse. Able to clear canyons in a single bound.", None, 'junk'),
'1087': ("They say only one heart piece in all of Hyrule will declare the holder a winner.", None, 'junk'),
# '1088': ("Are you stuck? Try asking for help in our Discord server or check out our Wiki!", None, 'junk'),
'1089': ("You would be surprised at all the things you can Hookshot in the Spirit Temple!", None, 'junk'),
'1090': ("I once glued a set of false teeth to the Boomerang.^${12 39 c7}That came back to bite me.", None, 'junk'), # sfx: Ganondorf laugh
'1091': ("They say that most of the water in Hyrule flows through King Zora's buttocks.", None, 'junk'),
'1092': ("Space, space, wanna go to space, yes, please space. Space space. Go to space.", None, 'junk'), # ref: Portal 2
'1093': ("They say that you must read the names of \"Special Deal\" items in shops carefully.", None, 'junk'),
'1094': ("Did you know that the Boomerang instantly stuns Phantom Ganon's second form?", None, 'junk'),
'1095': ("I came here to chew bubblegum and play rando. And I'm all out of bubblegum.", None, 'junk'), # ref: They Live
'1096': ("Did you know that Stalchildren leave you alone when wearing the Bunny Hood?", None, 'junk'),
'1097': ("This Gossip Stone Is Dedicated to Those Who Perished Before Ganon Was Defeated.", None, 'junk'),
'1098': ("Did you know that Blue Fire destroys mud walls and detonates Bomb Flowers?", None, 'junk'),
'1099': ("Are you sure you want to play this? Wanna go get some tacos or something?", None, 'junk'),
'1100': ("What did Zelda suggest that Link do when diplomacy didn't work?^${12 39 C7}Triforce.", None, 'junk'), # sfx: Ganondorf laugh
'1101': ("They say that bombing the hole Volvagia last flew into can be rewarding.", None, 'junk'),
'1102': ("Hi @, we've been trying to reach you about your horse's extended warranty.", None, 'junk'),
'1103': ("Ganondorf brushes his rotten teeth with salted slug flavoured tooth paste!", None, 'junk'), # ref: Banjo Kazooie
'1104': ("I'm Commander Shepard, and this is my favorite Gossip Stone in Hyrule!", None, 'junk'), # ref: Mass Effect
'1105': ("They say that tossing a bomb will cause a Blue Bubble to go after it.", None, 'junk'),
'1106': ("They say that the Lizalfos in Dodongo's Cavern like to play in lava.", None, 'junk'),
'1107': ("Why won't anyone acknowledge the housing crisis in Kakariko Village?", None, 'junk'),
'1108': ("Don't believe in yourself. Believe in the me that believes in you!", None, 'junk'), # ref: Anime
'1109': ("This is a haiku&Five syllables then seven&Five more to finish", None, 'junk'),
'1110': ("They say that beating Bongo Bongo quickly requires an even tempo.", None, 'junk'),
'1111': ("Did you know that you can tune a piano but you can't tune a fish?", None, 'junk'), # Studio Album by REO Speedwagon
'1112': ("You thought it would be a useful hint, but it was me, Junk Hint!", None, 'junk'), # ref: Jojo's Bizarre Adventure
'1113': ("They say you can cut corners to get to your destination faster.", None, 'junk'),
'1114': ("Three things are certain: death, taxes, and forgetting a check.", None, 'junk'), # ref: Benjamin Franklin, allegedly
'1115': ("Have you thought about going where the items are?^Just saying.", None, 'junk'),
'1116': ("They say that the true reward is the friends we made along the way.", None, 'junk'), # ref: common meme with unknown origins
'1117': ("Gossip Stone Shuffle must be on. I'm normally in Zora's Domain!", None, 'junk'),
'1118': ("When ASM is used to code a randomizer they should call it ASMR.", None, 'junk'),
'1119': ("It's so lonely being stuck here with nobody else to talk to...", None, 'junk'),
'1120': ("Why are they called Wallmasters if they come from the ceiling?", None, 'junk'),
'1121': ("They say that Zelda's Lullaby can be used to repair broken signs.", None, 'junk'),
'1122': ("Fell for it, didn't you, fool? Junk hint cross split attack!", None, 'junk'), # ref: Jojo's Bizarre Adventure
'1123': ("Please don't abandon this seed. Our world deserves saving!", None, 'junk'),
'1124': ("I wanna be a rocketship, @! Please help me live my dreams!", None, 'junk'),
'1125': ("They say that King Zora needs to build a taller fence.", None, 'junk'),
'1126': ("They say Goron fabrics protect against more than fire.", None, 'junk'),
'1127': ("Did you know that ReDead mourn their defeated friends?", None, 'junk'),
'1128': ("Did you know that ReDead eat their defeated friends?", None, 'junk'),
'1129': ("What is a Hylian? A miserable little pile of secrets!", None, 'junk'), # ref: Castlevania
'1130': ("The hint stone you have dialed&has been disconnected.", None, 'junk'), # ref: telephone error message
'1131': ("We don't make mistakes, we have happy accidents.", None, 'junk'), # ref: Bob Ross
'1132': ("I've heard Ganon dislikes lemon-flavored popsicles.", None, 'junk'),
'1133': ("If Gorons eat rocks, does that mean I'm in danger?", None, 'junk'),
'1134': ("They say Ingo is not very good at planning ahead.", None, 'junk'),
'1136': ("They say that Anju needs to stop losing her chickens.", None, 'junk'),
'1137': ("Can you move me? I don't get great service here.", None, 'junk'),
'1138': ("Have you embraced the power of the Deku Nut yet?", None, 'junk'),
'1139': ("They say that Mido is easily confused by sick flips.", None, 'junk'), # ref: Mido Skip
'1140': ("They say that the path to Termina is a one-way trip.", None, 'junk'), # ref: Majora's Mask
'1141': ("They say that @ deserves a hug. Everyone does!", None, 'junk'),
'1142': ("I hear Termina is a great spot for a vacation!", None, 'junk'), # ref: Majora's Mask
'1144': ("You've met with a terrible fate, haven't you?", None, 'junk'), # ref: Majora's Mask
'1145': ("Try using various items and weapons on me :)", None, 'junk'),
'1146': ("On second thought, let's not go to Hyrule Castle. 'Tis a silly place.", None, 'junk'), # ref: Monty Python
'1147': ("If you see something suspicious, bomb it!", None, 'junk'),
'1148': ("Don't forget to write down your hints :)", None, 'junk'),
'1149': ("Would you kindly...&close this textbox?", None, 'junk'), # ref: Bioshock
'1150': ("They say that King Dodongo dislikes smoke.", None, 'junk'), # ref: Zelda 1
'1151': ("Never give up. Trust your instincts!", None, 'junk'), # ref: Star Fox 64
'1152': ("I love to gossip! Wanna be friends?", None, 'junk'),
'1153': ("This isn't where I parked my horse!", None, 'junk'), # ref: EuroTrip
'1156': ("Anything not saved will be lost.", None, 'junk'), # ref: Nintendo (various games and platforms)
'1157': ("I was voted least helpful hint stone five years in a row!", None, 'junk'),
'1158': ("They say that the Groose is loose.", None, 'junk'), # ref: Skyward Sword
'1159': ("Twenty-three is number one!^And thirty-one is number two!", None, 'junk'), # ref: Deku Scrubs in Deku Tree
'1160': ("Ya ha ha! You found me!", None, 'junk'), # ref: Breath of the Wild
'1161': ("Do you like Like Likes?", None, 'junk'),
'1162': ("Next you'll say:^\"Why am I still reading these?\"", None, 'junk'), # ref: Jojo's Bizarre Adventure
'1165': ("You're a cool cat, @.", None, 'junk'),
'1167': ("This hint is in another castle.", None, 'junk'), # ref: Mario
'1169': ("Hydrate!", None, 'junk'),
'1170': ("They say that there is an alcove with a Recovery Heart behind the lava wall in Dodongo's Cavern.", None, 'junk'),
'1171': ("Having regrets? Reset without saving!", None, 'junk'),
'1172': ("Did you know that Gorons understood SRM long before speedrunners did?", None, 'junk'), # ref: Goron City murals
# '1173': ("Did you know that the Discord server has a public Plandomizer library?", None, 'junk'),
'1174': ("${12 28 DF}Moo!", None, 'junk'), # sfx: cow
'1175': ("${12 28 D8}Woof!", None, 'junk'), # sfx: dog
'1176': ("${12 68 08}Aah! You startled me!", None, 'junk'), # sfx: adult Link scream (when falling)
'1178': ("Use Multiworld to cross the gaps between worlds and engage in jolly co-operation!", None, 'junk'), # ref: Dark Souls
'1179': ("${12 68 51}What in tarnation!", None, 'junk'), # sfx: Talon surprised at being woken
'1180': ("Press \u00A5\u00A5\u00A6\u00A6\u00A7\u00A8\u00A7\u00A8\u00A0\u009F to warp to&the credits.", None, 'junk'), # ref: Konami Code
'1181': ("Oh!^Oh-oh!^C'mon!^Come on! Come on! Come on!^HOT!!^What a hot beat!^WHOOOOAH!^YEEEEAH!^YAHOOO!!", None, 'junk'), # ref: Darunia dancing
'1182': ("${12 68 5F}Hey! Listen!", None, 'junk'), # sfx: Navi: "Hey!"
'1183': ("I am the King of Gossip Stones, but fear not - I have the common touch! That means I can make conversation with everyone^from foreign dignitaries to the lowliest bumpkin - such as yourself!", None, 'junk'), # ref: Dragon Quest XI
'1184': ("I am @, hero of the Gossip Stones! Hear my name and tremble!", None, 'junk'), # ref: Link the Goron
'1185': ("Having trouble defeating Dark Link?^Look away from him while holding Z-Target and then when Dark Link walks up behind you, strafe sideways and slash your sword.", None, 'junk'),
'1186': ("They say that if Link could say a few words, he'd be a better public speaker.", None, 'junk'),
'1187': ("Did you know that you only need to play the Song of Time to open the Door of Time? The Spiritual Stones are not needed.", None, 'junk'),
'1188': ("Where did Anju meet her lover?^${12 39 C7}At a Kafei.", None, 'junk'), # ref: Majora's Mask / sfx: Ganondorf laugh
'1189': ("Did you know that you can access the Fire Temple boss door without dropping the pillar by using the Hover boots?", None, 'junk'),
'1190': ("Key-locked in Fire Temple? Maybe Volvagia has your Small Key.", None, 'junk'),
# '1191': ("Expired Spoiler Log? Don't worry! The OoTR Discord staff can help you out.", None, 'junk'),
'1192': ("Try holding a D-pad button on the item screen.", None, 'junk'),
'1193': ("Did you know that in the Forest Temple you can reach the alcove in the block push room with Hover Boots?", None, 'junk'),
'1194': ("Dodongo's Cavern is much easier and faster to clear as Adult.", None, 'junk'),
'1195': ("Did you know that the solution to the Truth Spinner in Shadow Temple is never one of the two positions closest to the initial position?", None, 'junk'),
'1196': ("Did you know that the Kokiri Sword is as effective as Deku Sticks against Dead Hand?", None, 'junk'),
'1197': ("Did you know that Ruto is strong enough to defeat enemies and activate ceiling switches inside Jabu Jabu's Belly?", None, 'junk'),
'1198': ("Did you know that Barinade, Volvagia and Twinrova hard require the Boomerang, Megaton Hammer and Mirror Shield, respectively?", None, 'junk'),
'1199': ("Did you know that Dark Link's max health is equal to @'s max health?", None, 'junk'),
'1200': ("Did you know that you can reach the invisible Hookshot target before the fans room in Shadow Temple with just the Hookshot if you backflip onto the chest?", None, 'junk'),
'1201': ("${12 68 54}Objection!", None, 'junk'), # ref: Ace Attorney / sfx: Ingo's BWAAAAAH
'1202': ("They say that in the castle courtyard you can see a portrait of a young Talon.", None, 'junk'), # ref: Talon = Mario joke
'1203': ("They say that Phantom Ganon is a big Louisa May Alcott fan.", None, 'junk'), # ref: The Poe Sisters are named after characters from one of her novels
'1204': ("Have you found all 41 Gossip Stones?^Only 40 of us give hints.", None, 'junk'), # The 41th stone is the Lake Hylia water level stone
'1205': ("It's time for you to look inward and begin asking yourself the big questions:^How did Medigoron get inside that hole, and how does he get out for the credits?", None, 'junk'), # ref: Avatar The Last Airbender
'1206': ("They say that Jabu Jabu is no longer a pescetarian in Master Quest.", None, 'junk'),
'1207': ("Why are the floating skulls called \"Bubbles\" and the floating bubbles \"Shaboms\"?", None, 'junk'),
'1208': ("Why aren't ReDead called ReAlive?", None, 'junk'),
'1209': ("${12 48 27}Songs are hard, aren't they?", None, 'junk'), # sfx: failing a song
'1210': ("Did you know that you can Boomerang items that are freestanding Heart Pieces in the unrandomized game?", None, 'junk'),
'1211': ("Did you know that ReDead won't attack if you walk very slowly?", None, 'junk'),
'1212': ("Did you know that ReDead and Gibdo have their own version of Sun's Song that freezes you?", None, 'junk'),
'1213': ("${12 28 B1}\u009F \u00A7\u00A8\u00A6 \u00A7\u00A8\u00A6 \u009F\u00A6 \u009F\u00A6 \u00A8\u00A7\u009F", None, 'junk'), # ref: Frogs 2 / sfx: Frogs
'1214': ("${12 28 A2}Help! I'm melting away!", None, 'junk'), # sfx: red ice melting
'1215': ("${12 38 80}Eek!^I'm a little shy...", None, 'junk'), # sfx: Scrub hurt/stunned by Link
'1216': ("Master, there is a 0 percent chance that this hint is useful in any way.", None, 'junk'), # ref: Skyward Sword
'1217': ("${12 48 0B}Here, have a heart <3", None, 'junk'), # sfx: get Recovery Heart
'1218': ("${12 48 03}Here, have a Rupee.", None, 'junk'), # sfx: get Rupee
'1219': ("${12 68 31}Don't forget to stand up and stretch regularly.", None, 'junk'), # sfx: child Link stretching and yawning
'1220': ("Remember that time you did that really embarrassing thing?^${12 68 3A}Yikes.", None, 'junk'), # sfx: child Link fall damage
'1221': ("@ tries to read the Gossip Stone...^${12 48 06}but he's standing on the wrong side of it!", None, 'junk'), # ref: Dragon Quest XI / sfx: error (e.g. trying to equip an item as the wrong age)
'1222': ("Plandomizer is a pathway to many abilities some consider to be... unnatural.", None, 'junk'), # ref: Star Wars
'1223': ("Did you know that you can have complete control over the item placement, item pool, and more, using Plandomizer?", None, 'junk'),
'1224': ("They say that the earth is round.^Just like pizza.", None, 'junk'),
'1225': ("${12 68 62}Keeeyaaaah!^What is this?! A Hylian?!", None, 'junk'), # ref: Ruto meeting Big Octo / sfx: Ruto screaming
'1226': ("For you, the day you read this hint was the most important day of your life.^But for me, it was Tuesday.", None, 'junk'), # ref: Street Fighter (the movie)
'1227': ("Did you know that Barinade is allergic to bananas?", None, 'junk'),
'1228': ("Have you seen my dodongo? Very large, eats everything, responds to \"King\".^Call Darunia in Goron City if found. Huge rupee reward!", None, 'junk'),
'1229': ("Having trouble breathing underwater?^Have you tried wearing more BLUE?", None, 'junk'),
# '1230': ("Hi! I'm currently on an exchange program from Termina.^They say that East Clock Town is on the way of the hero.", None, 'junk'), # ref: Majora's Mask
'1231': ("Why are you asking me? I don't have any answers! I'm just as confused as you are!", None, 'junk'),
'1232': ("What do you call a group of Gorons?^${12 39 C7}A rock band.", None, 'junk'), # sfx: Ganondorf laugh
'1233': ("When the moon hits Termina like a big pizza pie that's game over.", None, 'junk'), # ref: That's Amore by Dean Martin + Majora's Mask
'1234': ("Ganondorf doesn't specialize in hiding items, nor in keeping secrets for that matter.", None, 'junk'),
'1235': ("While you're wasting time reading this hint, the others are playing the seed.", None, 'junk'),
'1236': ("Have you ever tried hammering the ground or wall in a room with Torch Slugs, Flare Dancers, Tektites, Walltulas, Scrubs or Deku Babas?", None, 'junk'),
'1237': ("Did you know that there's a 1/201 chance per Rupee that the Zora from the diving minigame tosses a 500 Rupee?^Keep winning and the odds go up!", None, 'junk'),
'1238': ("J = 0;&while J < 10;& Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;& J++;^ Press \u009F;^break;", None, 'junk'), # \u009F = A button
'Deku Tree': ("an ancient tree", "the Deku Tree", 'dungeonName'),
'Dodongos Cavern': ("an immense cavern", "Dodongo's Cavern", 'dungeonName'),
'Jabu Jabus Belly': ("the belly of a deity", "Jabu Jabu's Belly", 'dungeonName'),
'Forest Temple': ("a deep forest", "Forest Temple", 'dungeonName'),
'Fire Temple': ("a high mountain", "Fire Temple", 'dungeonName'),
'Water Temple': ("a vast lake", "Water Temple", 'dungeonName'),
'Shadow Temple': ("the house of the dead", "Shadow Temple", 'dungeonName'),
'Spirit Temple': ("the goddess of the sand", "Spirit Temple", 'dungeonName'),
'Ice Cavern': ("a frozen maze", "Ice Cavern", 'dungeonName'),
'Bottom of the Well': ("a shadow\'s prison", "Bottom of the Well", 'dungeonName'),
'Gerudo Training Ground': ("the test of thieves", "Gerudo Training Ground", 'dungeonName'),
'Ganons Castle': ("a conquered citadel", "Inside Ganon's Castle", 'dungeonName'),
'Queen Gohma': ("One inside an #ancient tree#...", "One in the #Deku Tree#...", 'boss'),
'King Dodongo': ("One within an #immense cavern#...", "One in #Dodongo's Cavern#...", 'boss'),
'Barinade': ("One in the #belly of a deity#...", "One in #Jabu Jabu's Belly#...", 'boss'),
'Phantom Ganon': ("One in a #deep forest#...", "One in the #Forest Temple#...", 'boss'),
'Volvagia': ("One on a #high mountain#...", "One in the #Fire Temple#...", 'boss'),
'Morpha': ("One under a #vast lake#...", "One in the #Water Temple#...", 'boss'),
'Bongo Bongo': ("One within the #house of the dead#...", "One in the #Shadow Temple#...", 'boss'),
'Twinrova': ("One inside a #goddess of the sand#...", "One in the #Spirit Temple#...", 'boss'),
'Links Pocket': ("One in #@'s pocket#...", "One #@ already has#...", 'boss'),
'Forest Temple': ("a deep forest", "the Forest Temple", 'dungeonName'),
'Fire Temple': ("a high mountain", "the Fire Temple", 'dungeonName'),
'Water Temple': ("a vast lake", "the Water Temple", 'dungeonName'),
'Shadow Temple': ("the house of the dead", "the Shadow Temple", 'dungeonName'),
'Spirit Temple': ("the goddess of the sand", "the Spirit Temple", 'dungeonName'),
'Ice Cavern': ("a frozen maze", "the Ice Cavern", 'dungeonName'),
'Bottom of the Well': ("a shadow's prison", "the Bottom of the Well", 'dungeonName'),
'Gerudo Training Ground': ("the test of thieves", "the Gerudo Training Ground", 'dungeonName'),
'Ganons Castle': ("a conquered citadel", "inside Ganon's Castle", 'dungeonName'),
'bridge_vanilla': ("the #Shadow and Spirit Medallions# as well as the #Light Arrows#", None, 'bridge'),
'bridge_stones': ("Spiritual Stones", None, 'bridge'),
'bridge_medallions': ("Medallions", None, 'bridge'),
'bridge_dungeons': ("Spiritual Stones and Medallions", None, 'bridge'),
'bridge_tokens': ("Gold Skulltula Tokens", None, 'bridge'),
'bridge_hearts': ("hearts", None, 'bridge'),
'ganonBK_dungeon': ("hidden somewhere #inside its castle#", None, 'ganonBossKey'),
'ganonBK_regional': ("hidden somewhere #inside or nearby its castle#", None, 'ganonBossKey'),
'ganonBK_vanilla': ("kept in a big chest #inside its tower#", None, 'ganonBossKey'),
'ganonBK_overworld': ("hidden #outside of dungeons# in Hyrule", None, 'ganonBossKey'),
'ganonBK_any_dungeon': ("hidden #inside a dungeon# in Hyrule", None, 'ganonBossKey'),
'ganonBK_keysanity': ("hidden somewhere #in Hyrule#", None, 'ganonBossKey'),
'ganonBK_keysanity': ("hidden #anywhere in Hyrule#", None, 'ganonBossKey'),
'ganonBK_triforce': ("given to the Hero once the #Triforce# is completed", None, 'ganonBossKey'),
'ganonBK_medallions': ("Medallions", None, 'ganonBossKey'),
'ganonBK_stones': ("Spiritual Stones", None, 'ganonBossKey'),
'ganonBK_dungeons': ("Spiritual Stones and Medallions", None, 'ganonBossKey'),
'ganonBK_tokens': ("Gold Skulltula Tokens", None, 'ganonBossKey'),
'ganonBK_hearts': ("hearts", None, 'ganonBossKey'),
'lacs_vanilla': ("the #Shadow and Spirit Medallions#", None, 'lacs'),
'lacs_medallions': ("Medallions", None, 'lacs'),
'lacs_stones': ("Spiritual Stones", None, 'lacs'),
'lacs_dungeons': ("Spiritual Stones and Medallions", None, 'lacs'),
'lacs_tokens': ("Gold Skulltula Tokens", None, 'lacs'),
'lacs_hearts': ("hearts", None, 'lacs'),
'Spiritual Stone Text Start': ("3 Spiritual Stones found in Hyrule...", None, 'altar'),
'Child Altar Text End': ("\x13\x07Ye who may become a Hero...&Stand with the Ocarina and&play the Song of Time.", None, 'altar'),
@ -1238,7 +1525,6 @@ hintTable = {
'Adult Altar Text End': ("Together with the Hero of Time,&the awakened ones will bind the&evil and return the light of peace&to the world...", None, 'altar'),
'Validation Line': ("Hmph... Since you made it this far,&I'll let you know what glorious&prize of Ganon's you likely&missed out on in my tower.^Behold...^", None, 'validation line'),
'Light Arrow Location': ("Ha ha ha... You'll never beat me by&reflecting my lightning bolts&and unleashing the arrows from&", None, 'Light Arrow Location'),
'2001': ("Oh! It's @.&I was expecting someone called&Sheik. Do you know what&happened to them?", None, 'ganonLine'),
'2002': ("I knew I shouldn't have put the key&on the other side of my door.", None, 'ganonLine'),
'2003': ("Looks like it's time for a&round of tennis.", None, 'ganonLine'),
@ -1252,6 +1538,140 @@ hintTable = {
'2011': ("Today, let's begin down&'The Hero is Defeated' timeline.", None, 'ganonLine'),
}
# Table containing the groups of locations for the multi hints (dual, etc.)
# The is used in order to add the locations to the checked list
multiTable = {
'Deku Theater Rewards': ['Deku Theater Skull Mask', 'Deku Theater Mask of Truth'],
'HF Ocarina of Time Retrieval': ['HF Ocarina of Time Item', 'Song from Ocarina of Time'],
'HF Valley Grotto': ['HF Cow Grotto Cow', 'HF GS Cow Grotto'],
'Market Bombchu Bowling Rewards': ['Market Bombchu Bowling First Prize', 'Market Bombchu Bowling Second Prize'],
'ZR Frogs Rewards': ['ZR Frogs in the Rain', 'ZR Frogs Ocarina Game'],
'LH Lake Lab Pool': ['LH Lab Dive', 'LH GS Lab Crate'],
'LH Adult Bean Destination Checks': ['LH Freestanding PoH', 'LH Adult Fishing'],
'GV Pieces of Heart Ledges': ['GV Crate Freestanding PoH', 'GV Waterfall Freestanding PoH'],
'GF Horseback Archery Rewards': ['GF HBA 1000 Points', 'GF HBA 1500 Points'],
'Colossus Nighttime GS': ['Colossus GS Tree', 'Colossus GS Hill'],
'Graveyard Dampe Race Rewards': ['Graveyard Dampe Race Hookshot Chest', 'Graveyard Dampe Race Freestanding PoH'],
'Graveyard Royal Family Tomb Contents': ['Graveyard Royal Familys Tomb Chest', 'Song from Royal Familys Tomb'],
'DMC Child Upper Checks': ['DMC GS Crate', 'DMC Deku Scrub'],
'Haunted Wasteland Checks': ['Wasteland Chest', 'Wasteland GS'],
'Deku Tree MQ Basement GS': ['Deku Tree MQ GS Basement Graves Room','Deku Tree MQ GS Basement Back Room'],
'Dodongos Cavern Upper Business Scrubs': ['Dodongos Cavern Deku Scrub Near Bomb Bag Left', 'Dodongos Cavern Deku Scrub Near Bomb Bag Right'],
'Dodongos Cavern MQ Larvae Room': ['Dodongos Cavern MQ Larvae Room Chest', 'Dodongos Cavern MQ GS Larvae Room'],
'Fire Temple Lower Loop': ['Fire Temple Flare Dancer Chest', 'Fire Temple Boss Key Chest'],
'Fire Temple MQ Lower Loop': ['Fire Temple MQ Megaton Hammer Chest', 'Fire Temple MQ Map Chest'],
'Water Temple River Loop Chests': ['Water Temple Longshot Chest', 'Water Temple River Chest'],
'Water Temple River Checks': ['Water Temple GS River', 'Water Temple River Chest'],
'Water Temple North Basement Checks': ['Water Temple GS Near Boss Key Chest', 'Water Temple Boss Key Chest'],
'Water Temple MQ North Basement Checks': ['Water Temple MQ Freestanding Key', 'Water Temple MQ GS Freestanding Key Area'],
'Water Temple MQ Lower Checks': ['Water Temple MQ Boss Key Chest', 'Water Temple MQ Freestanding Key'],
'Spirit Temple Colossus Hands': ['Spirit Temple Silver Gauntlets Chest', 'Spirit Temple Mirror Shield Chest'],
'Spirit Temple Child Lower': ['Spirit Temple Child Bridge Chest', 'Spirit Temple Child Early Torches Chest'],
'Spirit Temple Child Top': ['Spirit Temple Sun Block Room Chest', 'Spirit Temple GS Hall After Sun Block Room'],
'Spirit Temple Adult Lower': ['Spirit Temple Early Adult Right Chest', 'Spirit Temple Compass Chest'],
'Spirit Temple MQ Child Top': ['Spirit Temple MQ Sun Block Room Chest', 'Spirit Temple MQ GS Sun Block Room'],
'Spirit Temple MQ Symphony Room': ['Spirit Temple MQ Symphony Room Chest', 'Spirit Temple MQ GS Symphony Room'],
'Spirit Temple MQ Throne Room GS': ['Spirit Temple MQ GS Nine Thrones Room West', 'Spirit Temple MQ GS Nine Thrones Room North'],
'Shadow Temple Invisible Blades Chests': ['Shadow Temple Invisible Blades Visible Chest', 'Shadow Temple Invisible Blades Invisible Chest'],
'Shadow Temple Single Pot Room': ['Shadow Temple Freestanding Key', 'Shadow Temple GS Single Giant Pot'],
'Shadow Temple Spike Walls Room': ['Shadow Temple Spike Walls Left Chest', 'Shadow Temple Boss Key Chest'],
'Shadow Temple MQ Upper Checks': ['Shadow Temple MQ Compass Chest', 'Shadow Temple MQ Hover Boots Chest'],
'Shadow Temple MQ Invisible Blades Chests': ['Shadow Temple MQ Invisible Blades Visible Chest', 'Shadow Temple MQ Invisible Blades Invisible Chest'],
'Shadow Temple MQ Spike Walls Room': ['Shadow Temple MQ Spike Walls Left Chest', 'Shadow Temple MQ Boss Key Chest'],
'Bottom of the Well Inner Rooms GS': ['Bottom of the Well GS West Inner Room', 'Bottom of the Well GS East Inner Room'],
'Bottom of the Well Dead Hand Room': ['Bottom of the Well Lens of Truth Chest', 'Bottom of the Well Invisible Chest'],
'Bottom of the Well MQ Dead Hand Room': ['Bottom of the Well MQ Compass Chest', 'Bottom of the Well MQ Dead Hand Freestanding Key'],
'Bottom of the Well MQ Basement': ['Bottom of the Well MQ GS Basement', 'Bottom of the Well MQ Lens of Truth Chest'],
'Ice Cavern Final Room': ['Ice Cavern Iron Boots Chest', 'Sheik in Ice Cavern'],
'Ice Cavern MQ Final Room': ['Ice Cavern MQ Iron Boots Chest', 'Sheik in Ice Cavern'],
'Ganons Castle Spirit Trial Chests': ['Ganons Castle Spirit Trial Crystal Switch Chest', 'Ganons Castle Spirit Trial Invisible Chest'],
}
misc_item_hint_table = {
'dampe_diary': {
'id': 0x5003,
'hint_location': 'Dampe Diary Hint',
'default_item': 'Progressive Hookshot',
'default_item_text': "Whoever reads this, please enter {area}. I will let you have my stretching, shrinking keepsake.^I'm waiting for you.&--Dampé",
'custom_item_text': "Whoever reads this, please enter {area}. I will let you have {item}.^I'm waiting for you.&--Dampé",
'default_item_fallback': "Whoever reads this, I'm sorry, but I seem to have #misplaced# my stretching, shrinking keepsake.&--Dampé",
'custom_item_fallback': "Whoever reads this, I'm sorry, but I seem to have #misplaced# {item}.&--Dampé",
'replace': {
"enter #your pocket#. I will let you have": "check #your pocket#. You will find",
},
'use_alt_hint': False,
'local_only': True,
},
'ganondorf': {
'id': 0x70CC,
'hint_location': 'Ganondorf Hint',
'default_item': 'Light Arrows',
'default_item_text': "Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from {area}!",
'custom_item_text': "Ha ha ha... You'll never find {item} from {area}!",
'replace': {
"from #inside Ganon's Castle#": "from #inside my castle#",
"from #outside Ganon's Castle#": "from #outside my castle#",
"from #Ganondorf's Chamber#": "from #those pots over there#",
},
'use_alt_hint': True,
'local_only': False,
},
}
misc_location_hint_table = {
'10_skulltulas': {
'id': 0x9004,
'hint_location': '10 Skulltulas Reward Hint',
'item_location': 'Kak 10 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4110 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'20_skulltulas': {
'id': 0x9005,
'hint_location': '20 Skulltulas Reward Hint',
'item_location': 'Kak 20 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4120 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'30_skulltulas': {
'id': 0x9006,
'hint_location': '30 Skulltulas Reward Hint',
'item_location': 'Kak 30 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4130 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'40_skulltulas': {
'id': 0x9007,
'hint_location': '40 Skulltulas Reward Hint',
'item_location': 'Kak 40 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4140 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
'50_skulltulas': {
'id': 0x9008,
'hint_location': '50 Skulltulas Reward Hint',
'item_location': 'Kak 50 Gold Skulltula Reward',
'location_text': "Yeaaarrgh! I'm cursed!! Please save me by destroying \x05\x4150 Spiders of the Curse\x05\x40 and I will give you \x05\x42{item}\x05\x40.",
'location_fallback': "Yeaaarrgh! I'm cursed!!",
},
}
# Separate table for goal names to avoid duplicates in the hint table.
# Link's Pocket will always be an empty goal, but it's included here to
# prevent key errors during the dungeon reward lookup.
goalTable = {
'Queen Gohma': ("path to the #Spider#", "path to #Queen Gohma#", "Green"),
'King Dodongo': ("path to the #Dinosaur#", "path to #King Dodongo#", "Red"),
'Barinade': ("path to the #Tentacle#", "path to #Barinade#", "Blue"),
'Phantom Ganon': ("path to the #Puppet#", "path to #Phantom Ganon#", "Green"),
'Volvagia': ("path to the #Dragon#", "path to #Volvagia#", "Red"),
'Morpha': ("path to the #Amoeba#", "path to #Morpha#", "Blue"),
'Bongo Bongo': ("path to the #Hands#", "path to #Bongo Bongo#", "Pink"),
'Twinrova': ("path to the #Witches#", "path to #Twinrova#", "Yellow"),
'Links Pocket': ("path to #Links Pocket#", "path to #Links Pocket#", "Light Blue"),
}
# This specifies which hints will never appear due to either having known or known useless contents or due to the locations not existing.
def hintExclusions(world, clear_cache=False):
@ -1272,10 +1692,13 @@ def hintExclusions(world, clear_cache=False):
hint = getHint(name, world.clearer_hints)
if any(item in hint.type for item in
['always',
'dual_always',
'sometimes',
'overworld',
'dungeon',
'song']):
'song',
'dual',
'exclude']):
location_hints.append(hint)
for hint in location_hints:
@ -1287,9 +1710,9 @@ def hintExclusions(world, clear_cache=False):
def nameIsLocation(name, hint_type, world):
if isinstance(hint_type, (list, tuple)):
for htype in hint_type:
if htype in ['sometimes', 'song', 'overworld', 'dungeon', 'always'] and name not in hintExclusions(world):
if htype in ['sometimes', 'song', 'overworld', 'dungeon', 'always', 'exclude'] and name not in hintExclusions(world):
return True
elif hint_type in ['sometimes', 'song', 'overworld', 'dungeon', 'always'] and name not in hintExclusions(world):
elif hint_type in ['sometimes', 'song', 'overworld', 'dungeon', 'always', 'exclude'] and name not in hintExclusions(world):
return True
return False

View File

@ -10,8 +10,10 @@ from urllib.error import URLError, HTTPError
import json
from enum import Enum
from BaseClasses import Region
from .Items import OOTItem
from .HintList import getHint, getHintGroup, Hint, hintExclusions
from .HintList import getHint, getHintGroup, Hint, hintExclusions, \
misc_item_hint_table, misc_location_hint_table
from .Messages import COLOR_MAP, update_message_by_id
from .TextBox import line_wrap
from .Utils import data_path, read_json
@ -24,7 +26,10 @@ bingoBottlesForHints = (
)
defaultHintDists = [
'balanced.json', 'bingo.json', 'ddr.json', 'scrubs.json', 'strong.json', 'tournament.json', 'useless.json', 'very_strong.json'
'async.json', 'balanced.json', 'bingo.json', 'chaos.json', 'coop2.json',
'ddr.json', 'league.json', 'mw3.json', 'scrubs.json', 'strong.json',
'tournament.json', 'useless.json', 'very_strong.json',
'very_strong_magic.json', 'weekly.json'
]
class RegionRestriction(Enum):
@ -294,6 +299,151 @@ class HintAreaNotFound(RuntimeError):
pass
class HintArea(Enum):
# internal name prepositions display name short name color internal dungeon name
# vague clear
ROOT = 'in', 'in', "Link's pocket", 'Free', 'White', None
HYRULE_FIELD = 'in', 'in', 'Hyrule Field', 'Hyrule Field', 'Light Blue', None
LON_LON_RANCH = 'at', 'at', 'Lon Lon Ranch', 'Lon Lon Ranch', 'Light Blue', None
MARKET = 'in', 'in', 'the Market', 'Market', 'Light Blue', None
TEMPLE_OF_TIME = 'inside', 'inside', 'the Temple of Time', 'Temple of Time', 'Light Blue', None
CASTLE_GROUNDS = 'on', 'on', 'the Castle Grounds', None, 'Light Blue', None # required for warp songs
HYRULE_CASTLE = 'at', 'at', 'Hyrule Castle', 'Hyrule Castle', 'Light Blue', None
OUTSIDE_GANONS_CASTLE = None, None, "outside Ganon's Castle", "Outside Ganon's Castle", 'Light Blue', None
INSIDE_GANONS_CASTLE = 'inside', None, "inside Ganon's Castle", "Inside Ganon's Castle", 'Light Blue', 'Ganons Castle'
GANONDORFS_CHAMBER = 'in', 'in', "Ganondorf's Chamber", "Ganondorf's Chamber", 'Light Blue', None
KOKIRI_FOREST = 'in', 'in', 'Kokiri Forest', "Kokiri Forest", 'Green', None
DEKU_TREE = 'inside', 'inside', 'the Deku Tree', "Deku Tree", 'Green', 'Deku Tree'
LOST_WOODS = 'in', 'in', 'the Lost Woods', "Lost Woods", 'Green', None
SACRED_FOREST_MEADOW = 'at', 'at', 'the Sacred Forest Meadow', "Sacred Forest Meadow", 'Green', None
FOREST_TEMPLE = 'in', 'in', 'the Forest Temple', "Forest Temple", 'Green', 'Forest Temple'
DEATH_MOUNTAIN_TRAIL = 'on', 'on', 'the Death Mountain Trail', "Death Mountain Trail", 'Red', None
DODONGOS_CAVERN = 'within', 'in', "Dodongo's Cavern", "Dodongo's Cavern", 'Red', 'Dodongos Cavern'
GORON_CITY = 'in', 'in', 'Goron City', "Goron City", 'Red', None
DEATH_MOUNTAIN_CRATER = 'in', 'in', 'the Death Mountain Crater', "Death Mountain Crater", 'Red', None
FIRE_TEMPLE = 'on', 'in', 'the Fire Temple', "Fire Temple", 'Red', 'Fire Temple'
ZORA_RIVER = 'at', 'at', "Zora's River", "Zora's River", 'Blue', None
ZORAS_DOMAIN = 'at', 'at', "Zora's Domain", "Zora's Domain", 'Blue', None
ZORAS_FOUNTAIN = 'at', 'at', "Zora's Fountain", "Zora's Fountain", 'Blue', None
JABU_JABUS_BELLY = 'in', 'inside', "Jabu Jabu's Belly", "Jabu Jabu's Belly", 'Blue', 'Jabu Jabus Belly'
ICE_CAVERN = 'inside', 'in' , 'the Ice Cavern', "Ice Cavern", 'Blue', 'Ice Cavern'
LAKE_HYLIA = 'at', 'at', 'Lake Hylia', "Lake Hylia", 'Blue', None
WATER_TEMPLE = 'under', 'in', 'the Water Temple', "Water Temple", 'Blue', 'Water Temple'
KAKARIKO_VILLAGE = 'in', 'in', 'Kakariko Village', "Kakariko Village", 'Pink', None
BOTTOM_OF_THE_WELL = 'within', 'at', 'the Bottom of the Well', "Bottom of the Well", 'Pink', 'Bottom of the Well'
GRAVEYARD = 'in', 'in', 'the Graveyard', "Graveyard", 'Pink', None
SHADOW_TEMPLE = 'within', 'in', 'the Shadow Temple', "Shadow Temple", 'Pink', 'Shadow Temple'
GERUDO_VALLEY = 'at', 'at', 'Gerudo Valley', "Gerudo Valley", 'Yellow', None
GERUDO_FORTRESS = 'at', 'at', "Gerudo's Fortress", "Gerudo's Fortress", 'Yellow', None
GERUDO_TRAINING_GROUND = 'within', 'on', 'the Gerudo Training Ground', "Gerudo Training Ground", 'Yellow', 'Gerudo Training Ground'
HAUNTED_WASTELAND = 'in', 'in', 'the Haunted Wasteland', "Haunted Wasteland", 'Yellow', None
DESERT_COLOSSUS = 'at', 'at', 'the Desert Colossus', "Desert Colossus", 'Yellow', None
SPIRIT_TEMPLE = 'inside', 'in', 'the Spirit Temple', "Spirit Temple", 'Yellow', 'Spirit Temple'
# Performs a breadth first search to find the closest hint area from a given spot (region, location, or entrance).
# May fail to find a hint if the given spot is only accessible from the root and not from any other region with a hint area
@staticmethod
def at(spot, use_alt_hint=False):
if isinstance(spot, Region):
original_parent = spot
else:
original_parent = spot.parent_region
already_checked = []
spot_queue = [spot]
while spot_queue:
current_spot = spot_queue.pop(0)
already_checked.append(current_spot)
if isinstance(current_spot, Region):
parent_region = current_spot
else:
parent_region = current_spot.parent_region
if parent_region.hint and (original_parent.name == 'Root' or parent_region.name != 'Root'):
if use_alt_hint and parent_region.alt_hint:
return parent_region.alt_hint
return parent_region.hint
spot_queue.extend(list(filter(lambda ent: ent not in already_checked, parent_region.entrances)))
raise HintAreaNotFound('No hint area could be found for %s [World %d]' % (spot, spot.world.player))
@classmethod
def for_dungeon(cls, dungeon_name: str):
if '(' in dungeon_name and ')' in dungeon_name:
# A dungeon item name was passed in - get the name of the dungeon from it.
dungeon_name = dungeon_name[dungeon_name.index('(') + 1:dungeon_name.index(')')]
if dungeon_name == "Thieves Hideout":
# Special case for Thieves' Hideout - change this if it gets its own hint area.
return HintArea.GERUDO_FORTRESS
for hint_area in cls:
if hint_area.dungeon_name == dungeon_name:
return hint_area
return None
def preposition(self, clearer_hints):
return self.value[1 if clearer_hints else 0]
def __str__(self):
return self.value[2]
# used for dungeon reward locations in the pause menu
@property
def short_name(self):
return self.value[3]
# Hint areas are further grouped into colored sections of the map by association with the medallions.
# These colors are used to generate the text boxes for shuffled warp songs.
@property
def color(self):
return self.value[4]
@property
def dungeon_name(self):
return self.value[5]
@property
def is_dungeon(self):
return self.dungeon_name is not None
def is_dungeon_item(self, item):
for dungeon in item.world.dungeons:
if dungeon.name == self.dungeon_name:
return dungeon.is_dungeon_item(item)
return False
# Formats the hint text for this area with proper grammar.
# Dungeons are hinted differently depending on the clearer_hints setting.
def text(self, clearer_hints, preposition=False, world=None):
if self.is_dungeon:
text = getHint(self.dungeon_name, clearer_hints).text
else:
text = str(self)
prefix, suffix = text.replace('#', '').split(' ', 1)
if world is None:
if prefix == "Link's":
text = f"@'s {suffix}"
else:
replace_prefixes = ('a', 'an', 'the')
move_prefixes = ('outside', 'inside')
if prefix in replace_prefixes:
text = f"world {world}'s {suffix}"
elif prefix in move_prefixes:
text = f"{prefix} world {world}'s {suffix}"
elif prefix == "Link's":
text = f"player {world}'s {suffix}"
else:
text = f"world {world}'s {text}"
if '#' not in text:
text = f'#{text}#'
if preposition and self.preposition(clearer_hints) is not None:
text = f'{self.preposition(clearer_hints)} {text}'
return text
# Peforms a breadth first search to find the closest hint area from a given spot (location or entrance)
# May fail to find a hint if the given spot is only accessible from the root and not from any other region with a hint area
# Returns the name of the location if the spot is not in OoT
@ -643,7 +793,7 @@ def buildWorldGossipHints(world, checkedLocations=None):
# If Ganondorf hints Light Arrows and is reachable without them, add to checkedLocations to prevent extra hinting
# Can only be forced with vanilla bridge or trials
if world.bridge != 'vanilla' and world.trials == 0 and world.misc_hints:
if world.bridge != 'vanilla' and world.trials == 0 and 'ganondorf' in world.misc_hints:
try:
light_arrow_location = world.multiworld.find_item("Light Arrows", world.player)
checkedLocations[light_arrow_location.player].add(light_arrow_location.name)
@ -885,12 +1035,17 @@ def buildAltarHints(world, messages, include_rewards=True, include_wincons=True)
# pulls text string from hintlist for reward after sending the location to hintlist.
def buildBossString(reward, color, world):
for location in world.multiworld.get_filled_locations(world.player):
if location.item.name == reward:
item_icon = chr(location.item.special['item_id'])
location_text = getHint(location.name, world.clearer_hints).text
return str(GossipText("\x08\x13%s%s" % (item_icon, location_text), [color], prefix='')) + '\x04'
return ''
item_icon = chr(world.create_item(reward).special['item_id'])
if world.multiworld.state.has(reward, world.player):
if world.clearer_hints:
text = GossipText(f"\x08\x13{item_icon}One #@ already has#...", [color], prefix='')
else:
text = GossipText(f"\x08\x13{item_icon}One in #@'s pocket#...", [color], prefix='')
else:
location = world.hinted_dungeon_reward_locations[reward]
location_text = HintArea.at(location).text(world.clearer_hints, preposition=True)
text = GossipText(f"\x08\x13{item_icon}One {location_text}...", [color], prefix='')
return str(text) + '\x04'
def buildBridgeReqsString(world):
@ -907,6 +1062,8 @@ def buildBridgeReqsString(world):
item_req_string = str(world.bridge_rewards) + ' ' + item_req_string
elif world.bridge == 'tokens':
item_req_string = str(world.bridge_tokens) + ' ' + item_req_string
elif world.bridge == 'hearts':
item_req_string = str(world.bridge_hearts) + ' ' + item_req_string
if '#' not in item_req_string:
item_req_string = '#%s#' % item_req_string
string += "The awakened ones will await for the Hero to collect %s." % item_req_string
@ -928,9 +1085,26 @@ def buildGanonBossKeyString(world):
item_req_string = str(world.lacs_rewards) + ' ' + item_req_string
elif world.lacs_condition == 'tokens':
item_req_string = str(world.lacs_tokens) + ' ' + item_req_string
elif world.lacs_condition == 'hearts':
item_req_string = str(world.lacs_hearts) + ' ' + item_req_string
if '#' not in item_req_string:
item_req_string = '#%s#' % item_req_string
bk_location_string = "provided by Zelda once %s are retrieved" % item_req_string
elif world.shuffle_ganon_bosskey in ['stones', 'medallions', 'dungeons', 'tokens', 'hearts']:
item_req_string = getHint('ganonBK_' + world.shuffle_ganon_bosskey, world.clearer_hints).text
if world.shuffle_ganon_bosskey == 'medallions':
item_req_string = str(world.ganon_bosskey_medallions) + ' ' + item_req_string
elif world.shuffle_ganon_bosskey == 'stones':
item_req_string = str(world.ganon_bosskey_stones) + ' ' + item_req_string
elif world.shuffle_ganon_bosskey == 'dungeons':
item_req_string = str(world.ganon_bosskey_rewards) + ' ' + item_req_string
elif world.shuffle_ganon_bosskey == 'tokens':
item_req_string = str(world.ganon_bosskey_tokens) + ' ' + item_req_string
elif world.shuffle_ganon_bosskey == 'hearts':
item_req_string = str(world.ganon_bosskey_hearts) + ' ' + item_req_string
if '#' not in item_req_string:
item_req_string = '#%s#' % item_req_string
bk_location_string = "automatically granted once %s are retrieved" % item_req_string
else:
bk_location_string = getHint('ganonBK_' + world.shuffle_ganon_bosskey, world.clearer_hints).text
string += "And the \x05\x41evil one\x05\x40's key will be %s." % bk_location_string
@ -950,30 +1124,52 @@ def buildGanonText(world, messages):
text = get_raw_text(ganonLines.pop().text)
update_message_by_id(messages, 0x70CB, text)
# light arrow hint or validation chest item
if world.starting_items['Light Arrows'] > 0:
text = get_raw_text(getHint('Light Arrow Location', world.clearer_hints).text)
text += "\x05\x42your pocket\x05\x40"
else:
try:
find_light_arrows = world.multiworld.find_item('Light Arrows', world.player)
text = get_raw_text(getHint('Light Arrow Location', world.clearer_hints).text)
location = find_light_arrows
location_hint = get_hint_area(location)
if world.player != location.player:
text += "\x05\x42%s's\x05\x40 %s" % (world.multiworld.get_player_name(location.player), get_raw_text(location_hint))
else:
location_hint = location_hint.replace('Ganon\'s Castle', 'my castle')
text += get_raw_text(location_hint)
except StopIteration:
text = get_raw_text(getHint('Validation Line', world.clearer_hints).text)
for location in world.multiworld.get_filled_locations(world.player):
if location.name == 'Ganons Tower Boss Key Chest':
text += get_raw_text(getHint(getItemGenericName(location.item), world.clearer_hints).text)
break
text += '!'
update_message_by_id(messages, 0x70CC, text)
# Modified from original. Uses optimized AP methods, no support for custom items.
def buildMiscItemHints(world, messages):
for hint_type, data in misc_item_hint_table.items():
if hint_type in world.misc_hints:
item_locations = world.multiworld.find_item_locations(data['default_item'], world.player)
if data['local_only']:
item_locations = [loc for loc in item_locations if loc.player == world.player]
if world.multiworld.state.has(data['default_item'], world.player) > 0:
text = data['default_item_text'].format(area='#your pocket#')
elif item_locations:
location = item_locations[0]
player_text = ''
if location.player != world.player:
player_text = world.multiworld.get_player_name(location.player) + "'s "
if location.game == 'Ocarina of Time':
area = HintArea.at(location, use_alt_hint=data['use_alt_hint']).text(world.clearer_hints, world=None)
else:
area = location.name
text = data['default_item_text'].format(area=(player_text + area))
elif 'default_item_fallback' in data:
text = data['default_item_fallback']
else:
text = getHint('Validation Line', world.clearer_hints).text
location = world.get_location('Ganons Tower Boss Key Chest')
text += f"#{getHint(getItemGenericName(location.item), world.clearer_hints).text}#"
for find, replace in data.get('replace', {}).items():
text = text.replace(find, replace)
update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')))
# Modified from original to use optimized AP methods
def buildMiscLocationHints(world, messages):
for hint_type, data in misc_location_hint_table.items():
text = data['location_fallback']
if hint_type in world.misc_hints:
location = world.get_location(data['item_location'])
item = location.item
item_text = getHint(getItemGenericName(item), world.clearer_hints).text
if item.player != world.player:
item_text += f' for {world.multiworld.get_player_name(item.player)}'
text = data['location_text'].format(item=item_text)
update_message_by_id(messages, data['id'], str(GossipText(text, ['Green'], prefix='')), 0x23)
def get_raw_text(string):

File diff suppressed because it is too large Load Diff

View File

@ -64,37 +64,37 @@ class OOTItem(Item):
# None -> Normal
# Item: (type, Progressive, GetItemID, special),
item_table = {
'Bombs (5)': ('Item', None, 0x01, None),
'Deku Nuts (5)': ('Item', None, 0x02, None),
'Bombs (5)': ('Item', None, 0x01, {'junk': 8}),
'Deku Nuts (5)': ('Item', None, 0x02, {'junk': 5}),
'Bombchus (10)': ('Item', True, 0x03, None),
'Boomerang': ('Item', True, 0x06, None),
'Deku Stick (1)': ('Item', None, 0x07, None),
'Deku Stick (1)': ('Item', None, 0x07, {'junk': 5}),
'Lens of Truth': ('Item', True, 0x0A, None),
'Megaton Hammer': ('Item', True, 0x0D, None),
'Cojiro': ('Item', True, 0x0E, None),
'Cojiro': ('Item', True, 0x0E, {'trade': True}),
'Bottle': ('Item', True, 0x0F, {'bottle': float('Inf')}),
'Bottle with Milk': ('Item', True, 0x14, {'bottle': float('Inf')}),
'Rutos Letter': ('Item', True, 0x15, None),
'Deliver Letter': ('Item', True, None, {'bottle': float('Inf')}),
'Sell Big Poe': ('Item', True, None, {'bottle': float('Inf')}),
'Magic Bean': ('Item', True, 0x16, None),
'Skull Mask': ('Item', True, 0x17, None),
'Spooky Mask': ('Item', None, 0x18, None),
'Keaton Mask': ('Item', None, 0x1A, None),
'Bunny Hood': ('Item', None, 0x1B, None),
'Mask of Truth': ('Item', True, 0x1C, None),
'Pocket Egg': ('Item', True, 0x1D, None),
'Pocket Cucco': ('Item', True, 0x1E, None),
'Odd Mushroom': ('Item', True, 0x1F, None),
'Odd Potion': ('Item', True, 0x20, None),
'Poachers Saw': ('Item', True, 0x21, None),
'Broken Sword': ('Item', True, 0x22, None),
'Prescription': ('Item', True, 0x23, None),
'Eyeball Frog': ('Item', True, 0x24, None),
'Eyedrops': ('Item', True, 0x25, None),
'Claim Check': ('Item', True, 0x26, None),
'Magic Bean': ('Item', True, 0x16, {'progressive': 10}),
'Skull Mask': ('Item', True, 0x17, {'trade': True}),
'Spooky Mask': ('Item', None, 0x18, {'trade': True}),
'Keaton Mask': ('Item', None, 0x1A, {'trade': True}),
'Bunny Hood': ('Item', None, 0x1B, {'trade': True}),
'Mask of Truth': ('Item', True, 0x1C, {'trade': True}),
'Pocket Egg': ('Item', True, 0x1D, {'trade': True}),
'Pocket Cucco': ('Item', True, 0x1E, {'trade': True}),
'Odd Mushroom': ('Item', True, 0x1F, {'trade': True}),
'Odd Potion': ('Item', True, 0x20, {'trade': True}),
'Poachers Saw': ('Item', True, 0x21, {'trade': True}),
'Broken Sword': ('Item', True, 0x22, {'trade': True}),
'Prescription': ('Item', True, 0x23, {'trade': True}),
'Eyeball Frog': ('Item', True, 0x24, {'trade': True}),
'Eyedrops': ('Item', True, 0x25, {'trade': True}),
'Claim Check': ('Item', True, 0x26, {'trade': True}),
'Kokiri Sword': ('Item', True, 0x27, None),
'Giants Knife': ('Item', True, 0x28, None),
'Giants Knife': ('Item', None, 0x28, None),
'Deku Shield': ('Item', None, 0x29, None),
'Hylian Shield': ('Item', None, 0x2A, None),
'Mirror Shield': ('Item', True, 0x2B, None),
@ -104,28 +104,27 @@ item_table = {
'Hover Boots': ('Item', True, 0x2F, None),
'Stone of Agony': ('Item', True, 0x39, None),
'Gerudo Membership Card': ('Item', True, 0x3A, None),
'Heart Container': ('Item', None, 0x3D, None),
'Piece of Heart': ('Item', None, 0x3E, None),
'Heart Container': ('Item', True, 0x3D, {'alias': ('Piece of Heart', 4), 'progressive': float('Inf')}),
'Piece of Heart': ('Item', True, 0x3E, {'progressive': float('Inf')}),
'Boss Key': ('BossKey', True, 0x3F, None),
'Compass': ('Compass', None, 0x40, None),
'Map': ('Map', None, 0x41, None),
'Small Key': ('SmallKey', True, 0x42, {'progressive': float('Inf')}),
'Weird Egg': ('Item', True, 0x47, None),
'Recovery Heart': ('Item', None, 0x48, None),
'Arrows (5)': ('Item', None, 0x49, None),
'Arrows (10)': ('Item', None, 0x4A, None),
'Arrows (30)': ('Item', None, 0x4B, None),
'Rupee (1)': ('Item', None, 0x4C, None),
'Rupees (5)': ('Item', None, 0x4D, None),
'Rupees (20)': ('Item', None, 0x4E, None),
'Heart Container (Boss)': ('Item', None, 0x4F, None),
'Weird Egg': ('Item', True, 0x47, {'trade': True}),
'Recovery Heart': ('Item', None, 0x48, {'junk': 0}),
'Arrows (5)': ('Item', None, 0x49, {'junk': 8}),
'Arrows (10)': ('Item', None, 0x4A, {'junk': 2}),
'Arrows (30)': ('Item', None, 0x4B, {'junk': 0}),
'Rupee (1)': ('Item', None, 0x4C, {'junk': -1}),
'Rupees (5)': ('Item', None, 0x4D, {'junk': 10}),
'Rupees (20)': ('Item', None, 0x4E, {'junk': 4}),
'Milk': ('Item', None, 0x50, None),
'Goron Mask': ('Item', None, 0x51, None),
'Zora Mask': ('Item', None, 0x52, None),
'Gerudo Mask': ('Item', None, 0x53, None),
'Rupees (50)': ('Item', None, 0x55, None),
'Rupees (200)': ('Item', None, 0x56, None),
'Biggoron Sword': ('Item', True, 0x57, None),
'Rupees (50)': ('Item', None, 0x55, {'junk': 1}),
'Rupees (200)': ('Item', None, 0x56, {'junk': 0}),
'Biggoron Sword': ('Item', None, 0x57, None),
'Fire Arrows': ('Item', True, 0x58, None),
'Ice Arrows': ('Item', True, 0x59, None),
'Light Arrows': ('Item', True, 0x5A, None),
@ -133,15 +132,15 @@ item_table = {
'Dins Fire': ('Item', True, 0x5C, None),
'Nayrus Love': ('Item', True, 0x5E, None),
'Farores Wind': ('Item', True, 0x5D, None),
'Deku Nuts (10)': ('Item', None, 0x64, None),
'Bombs (10)': ('Item', None, 0x66, None),
'Bombs (20)': ('Item', None, 0x67, None),
'Deku Seeds (30)': ('Item', None, 0x69, None),
'Deku Nuts (10)': ('Item', None, 0x64, {'junk': 0}),
'Bombs (10)': ('Item', None, 0x66, {'junk': 2}),
'Bombs (20)': ('Item', None, 0x67, {'junk': 0}),
'Deku Seeds (30)': ('Item', None, 0x69, {'junk': 5}),
'Bombchus (5)': ('Item', True, 0x6A, None),
'Bombchus (20)': ('Item', True, 0x6B, None),
'Rupee (Treasure Chest Game)': ('Item', None, 0x72, None),
'Piece of Heart (Treasure Chest Game)': ('Item', None, 0x76, None),
'Ice Trap': ('Item', None, 0x7C, None),
'Piece of Heart (Treasure Chest Game)': ('Item', True, 0x76, {'alias': ('Piece of Heart', 1), 'progressive': float('Inf')}),
'Ice Trap': ('Item', None, 0x7C, {'junk': 0}),
'Progressive Hookshot': ('Item', True, 0x80, {'progressive': 2}),
'Progressive Strength Upgrade': ('Item', True, 0x81, {'progressive': 3}),
'Bomb Bag': ('Item', True, 0x82, None),
@ -169,26 +168,26 @@ item_table = {
'Boss Key (Spirit Temple)': ('BossKey', True, 0x98, None),
'Boss Key (Shadow Temple)': ('BossKey', True, 0x99, None),
'Boss Key (Ganons Castle)': ('GanonBossKey', True, 0x9A, None),
'Compass (Deku Tree)': ('Compass', None, 0x9B, None),
'Compass (Dodongos Cavern)': ('Compass', None, 0x9C, None),
'Compass (Jabu Jabus Belly)': ('Compass', None, 0x9D, None),
'Compass (Forest Temple)': ('Compass', None, 0x9E, None),
'Compass (Fire Temple)': ('Compass', None, 0x9F, None),
'Compass (Water Temple)': ('Compass', None, 0xA0, None),
'Compass (Spirit Temple)': ('Compass', None, 0xA1, None),
'Compass (Shadow Temple)': ('Compass', None, 0xA2, None),
'Compass (Bottom of the Well)': ('Compass', None, 0xA3, None),
'Compass (Ice Cavern)': ('Compass', None, 0xA4, None),
'Map (Deku Tree)': ('Map', None, 0xA5, None),
'Map (Dodongos Cavern)': ('Map', None, 0xA6, None),
'Map (Jabu Jabus Belly)': ('Map', None, 0xA7, None),
'Map (Forest Temple)': ('Map', None, 0xA8, None),
'Map (Fire Temple)': ('Map', None, 0xA9, None),
'Map (Water Temple)': ('Map', None, 0xAA, None),
'Map (Spirit Temple)': ('Map', None, 0xAB, None),
'Map (Shadow Temple)': ('Map', None, 0xAC, None),
'Map (Bottom of the Well)': ('Map', None, 0xAD, None),
'Map (Ice Cavern)': ('Map', None, 0xAE, None),
'Compass (Deku Tree)': ('Compass', False, 0x9B, None),
'Compass (Dodongos Cavern)': ('Compass', False, 0x9C, None),
'Compass (Jabu Jabus Belly)': ('Compass', False, 0x9D, None),
'Compass (Forest Temple)': ('Compass', False, 0x9E, None),
'Compass (Fire Temple)': ('Compass', False, 0x9F, None),
'Compass (Water Temple)': ('Compass', False, 0xA0, None),
'Compass (Spirit Temple)': ('Compass', False, 0xA1, None),
'Compass (Shadow Temple)': ('Compass', False, 0xA2, None),
'Compass (Bottom of the Well)': ('Compass', False, 0xA3, None),
'Compass (Ice Cavern)': ('Compass', False, 0xA4, None),
'Map (Deku Tree)': ('Map', False, 0xA5, None),
'Map (Dodongos Cavern)': ('Map', False, 0xA6, None),
'Map (Jabu Jabus Belly)': ('Map', False, 0xA7, None),
'Map (Forest Temple)': ('Map', False, 0xA8, None),
'Map (Fire Temple)': ('Map', False, 0xA9, None),
'Map (Water Temple)': ('Map', False, 0xAA, None),
'Map (Spirit Temple)': ('Map', False, 0xAB, None),
'Map (Shadow Temple)': ('Map', False, 0xAC, None),
'Map (Bottom of the Well)': ('Map', False, 0xAD, None),
'Map (Ice Cavern)': ('Map', False, 0xAE, None),
'Small Key (Forest Temple)': ('SmallKey', True, 0xAF, {'progressive': float('Inf')}),
'Small Key (Fire Temple)': ('SmallKey', True, 0xB0, {'progressive': float('Inf')}),
'Small Key (Water Temple)': ('SmallKey', True, 0xB1, {'progressive': float('Inf')}),
@ -198,10 +197,11 @@ item_table = {
'Small Key (Gerudo Training Ground)': ('SmallKey', True, 0xB5, {'progressive': float('Inf')}),
'Small Key (Thieves Hideout)': ('HideoutSmallKey', True, 0xB6, {'progressive': float('Inf')}),
'Small Key (Ganons Castle)': ('SmallKey', True, 0xB7, {'progressive': float('Inf')}),
'Double Defense': ('Item', True, 0xB8, None),
'Magic Bean Pack': ('Item', True, 0xC9, None),
'Double Defense': ('Item', None, 0xB8, None),
'Buy Magic Bean': ('Item', True, 0x16, {'alias': ('Magic Bean', 10), 'progressive': 10}),
'Magic Bean Pack': ('Item', True, 0xC9, {'alias': ('Magic Bean', 10), 'progressive': 10}),
'Triforce Piece': ('Item', True, 0xCA, {'progressive': float('Inf')}),
'Zeldas Letter': ('Item', True, 0x0B, None),
'Zeldas Letter': ('Item', True, 0x0B, {'trade': True}),
'Time Travel': ('Event', True, None, None),
'Scarecrow Song': ('Event', True, None, None),
'Triforce': ('Event', True, None, None),
@ -224,6 +224,7 @@ item_table = {
'Bugs': ('Drop', True, None, None),
'Big Poe': ('Drop', True, None, None),
'Bombchu Drop': ('Drop', True, None, None),
'Deku Shield Drop': ('Drop', True, None, None),
# Consumable refills defined mostly to placate 'starting with' options
'Arrows': ('Refill', None, None, None),
@ -306,15 +307,25 @@ item_table = {
'item_id': 0x65,
}),
'Small Key Ring (Forest Temple)': ('SmallKey', True, 0xCB, {'alias': ('Small Key (Forest Temple)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Fire Temple)': ('SmallKey', True, 0xCC, {'alias': ('Small Key (Fire Temple)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Water Temple)': ('SmallKey', True, 0xCD, {'alias': ('Small Key (Water Temple)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Spirit Temple)': ('SmallKey', True, 0xCE, {'alias': ('Small Key (Spirit Temple)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Shadow Temple)': ('SmallKey', True, 0xCF, {'alias': ('Small Key (Shadow Temple)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Bottom of the Well)': ('SmallKey', True, 0xD0, {'alias': ('Small Key (Bottom of the Well)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Gerudo Training Ground)': ('SmallKey', True, 0xD1, {'alias': ('Small Key (Gerudo Training Ground)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Thieves Hideout)': ('HideoutSmallKey', True, 0xD2, {'alias': ('Small Key (Thieves Hideout)', 10), 'progressive': float('Inf')}),
'Small Key Ring (Ganons Castle)': ('SmallKey', True, 0xD3, {'alias': ('Small Key (Ganons Castle)', 10), 'progressive': float('Inf')}),
'Buy Deku Nut (5)': ('Shop', True, 0x00, {'object': 0x00BB, 'price': 15}),
'Buy Arrows (30)': ('Shop', False, 0x01, {'object': 0x00D8, 'price': 60}),
'Buy Arrows (50)': ('Shop', False, 0x02, {'object': 0x00D8, 'price': 90}),
'Buy Bombs (5) [25]': ('Shop', False, 0x03, {'object': 0x00CE, 'price': 25}),
'Buy Bombs (5) for 25 Rupees': ('Shop', False, 0x03, {'object': 0x00CE, 'price': 25}),
'Buy Deku Nut (10)': ('Shop', True, 0x04, {'object': 0x00BB, 'price': 30}),
'Buy Deku Stick (1)': ('Shop', True, 0x05, {'object': 0x00C7, 'price': 10}),
'Buy Bombs (10)': ('Shop', False, 0x06, {'object': 0x00CE, 'price': 50}),
'Buy Fish': ('Shop', True, 0x07, {'object': 0x00F4, 'price': 200}),
'Buy Red Potion [30]': ('Shop', False, 0x08, {'object': 0x00EB, 'price': 30}),
'Buy Red Potion for 30 Rupees': ('Shop', False, 0x08, {'object': 0x00EB, 'price': 30}),
'Buy Green Potion': ('Shop', False, 0x09, {'object': 0x00EB, 'price': 30}),
'Buy Blue Potion': ('Shop', False, 0x0A, {'object': 0x00EB, 'price': 100}),
'Buy Hylian Shield': ('Shop', True, 0x0C, {'object': 0x00DC, 'price': 80}),
@ -334,9 +345,9 @@ item_table = {
'Buy Arrows (10)': ('Shop', False, 0x2C, {'object': 0x00D8, 'price': 20}),
'Buy Bombs (20)': ('Shop', False, 0x2D, {'object': 0x00CE, 'price': 80}),
'Buy Bombs (30)': ('Shop', False, 0x2E, {'object': 0x00CE, 'price': 120}),
'Buy Bombs (5) [35]': ('Shop', False, 0x2F, {'object': 0x00CE, 'price': 35}),
'Buy Red Potion [40]': ('Shop', False, 0x30, {'object': 0x00EB, 'price': 40}),
'Buy Red Potion [50]': ('Shop', False, 0x31, {'object': 0x00EB, 'price': 50}),
'Buy Bombs (5) for 35 Rupees': ('Shop', False, 0x2F, {'object': 0x00CE, 'price': 35}),
'Buy Red Potion for 40 Rupees': ('Shop', False, 0x30, {'object': 0x00EB, 'price': 40}),
'Buy Red Potion for 50 Rupees': ('Shop', False, 0x31, {'object': 0x00EB, 'price': 50}),
'Kokiri Emerald': ('DungeonReward', True, None,
{

View File

@ -1,7 +1,7 @@
MIT License
Copyright (c) 2017 Amazing Ampharos
Copyright (c) 2021 espeon65536
Copyright (c) 2022 espeon65536
Credit for contributions to Junglechief87 on this and to LLCoolDave and
KevinCathcart for their work on the Zelda Lttp Entrance Randomizer which

View File

@ -1,14 +1,37 @@
from enum import Enum
from .LocationList import location_table
from BaseClasses import Location
location_id_offset = 67000
location_name_to_id = {name: (location_id_offset + index) for (index, name) in enumerate(location_table)
if location_table[name][0] not in ['Boss', 'Event', 'Drop', 'HintStone', 'Hint']}
locnames_pre_70 = {
"Gift from Sages",
"ZR Frogs Zeldas Lullaby",
"ZR Frogs Eponas Song",
"ZR Frogs Sarias Song",
"ZR Frogs Suns Song",
"ZR Frogs Song of Time",
}
loctypes_70 = {'Beehive', 'Pot', 'FlyingPot', 'Crate', 'SmallCrate', 'RupeeTower', 'Freestanding', 'ActorOverride'}
new_name_order = sorted(location_table.keys(),
key=lambda name: 2 if location_table[name][0] in loctypes_70
else 1 if name in locnames_pre_70
else 0)
location_name_to_id = {name: (location_id_offset + index) for (index, name) in enumerate(new_name_order)
if location_table[name][0] not in {'Boss', 'Event', 'Drop', 'HintStone', 'Hint'}}
class DisableType(Enum):
ENABLED = 0
PENDING = 1
DISABLED = 2
class OOTLocation(Location):
game: str = 'Ocarina of Time'
def __init__(self, player, name='', code=None, address1=None, address2=None, default=None, type='Chest', scene=None, parent=None, filter_tags=None, internal=False):
def __init__(self, player, name='', code=None, address1=None, address2=None,
default=None, type='Chest', scene=None, parent=None, filter_tags=None,
internal=False, vanilla_item=None
):
super(OOTLocation, self).__init__(player, name, code, parent)
self.address1 = address1
self.address2 = address2
@ -16,15 +39,21 @@ class OOTLocation(Location):
self.type = type
self.scene = scene
self.internal = internal
self.vanilla_item = vanilla_item
if filter_tags is None:
self.filter_tags = None
else:
self.filter_tags = list(filter_tags)
self.never = False # no idea what this does
self.disabled = DisableType.ENABLED
if type == 'Event':
self.event = True
@property
def dungeon(self):
return self.parent_region.dungeon
def LocationFactory(locations, player: int):
ret = []
@ -42,7 +71,10 @@ def LocationFactory(locations, player: int):
if addresses is None:
addresses = (None, None)
address1, address2 = addresses
ret.append(OOTLocation(player, match_location, location_name_to_id.get(match_location, None), address1, address2, default, type, scene, filter_tags=filter_tags))
ret.append(OOTLocation(player, match_location,
location_name_to_id.get(match_location, None),
address1, address2, default, type, scene,
filter_tags=filter_tags, vanilla_item=vanilla_item))
else:
raise KeyError('Unknown Location: %s', location)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,9 @@
# text details: https://wiki.cloudmodding.com/oot/Text_Format
import logging
import random
from .HintList import misc_item_hint_table, misc_location_hint_table
from .TextBox import line_wrap
from .Utils import find_last
TEXT_START = 0x92D000
ENG_TEXT_SIZE_LIMIT = 0x39000
@ -51,38 +52,39 @@ CONTROL_CODES = {
0x1F: ('time', 0, lambda _: '<current time>' ),
}
# Maps unicode characters to corresponding bytes in OOTR's character set.
CHARACTER_MAP = {
'': 0x9F,
'': 0xA0,
'': 0xA1,
'': 0xA2,
'': 0xA3,
'': 0xA4,
'': 0xA5,
'': 0xA6,
'': 0xA7,
'': 0xA8,
chr(0xA9): 0xA9, # Down arrow -- not sure what best supports this
chr(0xAA): 0xAA, # Analog stick -- not sure what best supports this
}
# Support other ways of directly specifying controller inputs in OOTR's character set.
# (This is backwards-compatibility support for ShadowShine57's previous patch.)
CHARACTER_MAP.update(tuple((chr(v), v) for v in CHARACTER_MAP.values()))
# Characters 0x20 thru 0x7D map perfectly. range() excludes the last element.
CHARACTER_MAP.update((chr(c), c) for c in range(0x20, 0x7e))
# Other characters, source: https://wiki.cloudmodding.com/oot/Text_Format
CHARACTER_MAP.update((c, ix) for ix, c in enumerate(
(
'\u203e' # 0x7f
'ÀîÂÄÇÈÉÊËÏÔÖÙÛÜß' # 0x80 .. #0x8f
'àáâäçèéêëïôöùûü' # 0x90 .. #0x9e
),
start=0x7f
))
SPECIAL_CHARACTERS = {
0x80: 'À',
0x81: 'Á',
0x82: 'Â',
0x83: 'Ä',
0x84: 'Ç',
0x85: 'È',
0x86: 'É',
0x87: 'Ê',
0x88: 'Ë',
0x89: 'Ï',
0x8A: 'Ô',
0x8B: 'Ö',
0x8C: 'Ù',
0x8D: 'Û',
0x8E: 'Ü',
0x8F: 'ß',
0x90: 'à',
0x91: 'á',
0x92: 'â',
0x93: 'ä',
0x94: 'ç',
0x95: 'è',
0x96: 'é',
0x97: 'ê',
0x98: 'ë',
0x99: 'ï',
0x9A: 'ô',
0x9B: 'ö',
0x9C: 'ù',
0x9D: 'û',
0x9E: 'ü',
0x9F: '[A]',
0xA0: '[B]',
0xA1: '[C]',
@ -97,44 +99,16 @@ SPECIAL_CHARACTERS = {
0xAA: '[Control Stick]',
}
UTF8_TO_OOT_SPECIAL = {
(0xc3, 0x80): 0x80,
(0xc3, 0xae): 0x81,
(0xc3, 0x82): 0x82,
(0xc3, 0x84): 0x83,
(0xc3, 0x87): 0x84,
(0xc3, 0x88): 0x85,
(0xc3, 0x89): 0x86,
(0xc3, 0x8a): 0x87,
(0xc3, 0x8b): 0x88,
(0xc3, 0x8f): 0x89,
(0xc3, 0x94): 0x8A,
(0xc3, 0x96): 0x8B,
(0xc3, 0x99): 0x8C,
(0xc3, 0x9b): 0x8D,
(0xc3, 0x9c): 0x8E,
(0xc3, 0x9f): 0x8F,
(0xc3, 0xa0): 0x90,
(0xc3, 0xa1): 0x91,
(0xc3, 0xa2): 0x92,
(0xc3, 0xa4): 0x93,
(0xc3, 0xa7): 0x94,
(0xc3, 0xa8): 0x95,
(0xc3, 0xa9): 0x96,
(0xc3, 0xaa): 0x97,
(0xc3, 0xab): 0x98,
(0xc3, 0xaf): 0x99,
(0xc3, 0xb4): 0x9A,
(0xc3, 0xb6): 0x9B,
(0xc3, 0xb9): 0x9C,
(0xc3, 0xbb): 0x9D,
(0xc3, 0xbc): 0x9E,
}
REVERSE_MAP = list(chr(x) for x in range(256))
for char, byte in CHARACTER_MAP.items():
SPECIAL_CHARACTERS.setdefault(byte, char)
REVERSE_MAP[byte] = char
# [0x0500,0x0560] (inclusive) are reserved for plandomakers
GOSSIP_STONE_MESSAGES = list( range(0x0401, 0x04FF) ) # ids of the actual hints
GOSSIP_STONE_MESSAGES += [0x2053, 0x2054] # shared initial stone messages
TEMPLE_HINTS_MESSAGES = [0x7057, 0x707A] # dungeon reward hints from the temple of time pedestal
LIGHT_ARROW_HINT = [0x70CC] # ganondorf's light arrow hint line
GS_TOKEN_MESSAGES = [0x00B4, 0x00B5] # Get Gold Skulltula Token messages
ERROR_MESSAGE = 0x0001
@ -248,12 +222,13 @@ ITEM_MESSAGES = {
0x00B4: "\x08You got a \x05\x41Gold Skulltula Token\x05\x40!\x01You've collected \x05\x41\x19\x05\x40 tokens in total.",
0x00B5: "\x08You destroyed a \x05\x41Gold Skulltula\x05\x40.\x01You got a token proving you \x01destroyed it!", #Unused
0x00C2: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Collect four pieces total to get\x01another Heart Container.",
0x90C2: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01You are already at\x01maximum health.",
0x00C3: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01So far, you've collected two \x01pieces.",
0x00C4: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Now you've collected three \x01pieces!",
0x00C5: "\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01You've completed another Heart\x01Container!",
0x00C6: "\x08\x13\x72You got a \x05\x41Heart Container\x05\x40!\x01Your maximum life energy is \x01increased by one heart.",
0x90C6: "\x08\x13\x72You got a \x05\x41Heart Container\x05\x40!\x01You are already at\x01maximum health.",
0x00C7: "\x08\x13\x74You got the \x05\x41Boss Key\x05\x40!\x01Now you can get inside the \x01chamber where the Boss lurks.",
0x9002: "\x08You are a \x05\x43FOOL\x05\x40!",
0x00CC: "\x08You got a \x05\x43Blue Rupee\x05\x40!\x01That's \x05\x43five Rupees\x05\x40!",
0x00CD: "\x08\x13\x53You got the \x05\x43Silver Scale\x05\x40!\x01You can dive deeper than you\x01could before.",
0x00CE: "\x08\x13\x54You got the \x05\x43Golden Scale\x05\x40!\x01Now you can dive much\x01deeper than you could before!",
@ -274,6 +249,12 @@ ITEM_MESSAGES = {
0x00F1: "\x08You got a \x05\x45Purple Rupee\x05\x40!\x01That's \x05\x45fifty Rupees\x05\x40!",
0x00F2: "\x08You got a \x05\x46Huge Rupee\x05\x40!\x01This Rupee is worth a whopping\x01\x05\x46two hundred Rupees\x05\x40!",
0x00F9: "\x08\x13\x1EYou put a \x05\x41Big Poe \x05\x40in a bottle!\x01Let's sell it at the \x05\x41Ghost Shop\x05\x40!\x01Something good might happen!",
0x00FA: "\x08\x06\x49\x05\x41WINNER\x05\x40!\x04\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Collect four pieces total to get\x01another Heart Container.",
0x00FB: "\x08\x06\x49\x05\x41WINNER\x05\x40!\x04\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01So far, you've collected two \x01pieces.",
0x00FC: "\x08\x06\x49\x05\x41WINNER\x05\x40!\x04\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01Now you've collected three \x01pieces!",
0x00FD: "\x08\x06\x49\x05\x41WINNER\x05\x40!\x04\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01You've completed another Heart\x01Container!",
0x90FA: "\x08\x06\x49\x05\x41WINNER\x05\x40!\x04\x08\x13\x73You got a \x05\x41Piece of Heart\x05\x40!\x01You are already at\x01maximum health.",
0x9002: "\x08You are a \x05\x43FOOL\x05\x40!",
0x9003: "\x08You found a piece of the \x05\x41Triforce\x05\x40!",
0x9097: "\x08You got an \x05\x41Archipelago item\x05\x40!\x01It seems \x05\x41important\x05\x40!",
0x9098: "\x08You got an \x05\x43Archipelago item\x05\x40!\x01Doesn't seem like it's needed.",
@ -307,7 +288,7 @@ KEYSANITY_MESSAGES = {
0x0094: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09",
0x0095: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09",
0x009B: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09",
0x009F: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Gerudo Training\x01Grounds\x05\x40!\x09",
0x009F: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Gerudo Training\x01Ground\x05\x40!\x09",
0x00A0: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Thieves' Hideout\x05\x40!\x09",
0x00A1: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for \x05\x41Ganon's Castle\x05\x40!\x09",
0x00A2: "\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09",
@ -315,6 +296,15 @@ KEYSANITY_MESSAGES = {
0x00A5: "\x13\x76\x08You found the \x05\x41Dungeon Map\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09",
0x00A6: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09",
0x00A9: "\x13\x77\x08You found a \x05\x41Small Key\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09",
0x9010: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x42Forest Temple\x05\x40!\x09",
0x9011: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x41Fire Temple\x05\x40!\x09",
0x9012: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x43Water Temple\x05\x40!\x09",
0x9013: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x46Spirit Temple\x05\x40!\x09",
0x9014: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x45Shadow Temple\x05\x40!\x09",
0x9015: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x45Bottom of the Well\x05\x40!\x09",
0x9016: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x46Gerudo Training\x01Ground\x05\x40!\x09",
0x9017: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for the \x05\x46Thieves' Hideout\x05\x40!\x09",
0x9018: "\x13\x77\x08You found a \x05\x41Small Key Ring\x05\x40\x01for \x05\x41Ganon's Castle\x05\x40!\x09",
}
COLOR_MAP = {
@ -338,7 +328,18 @@ MISC_MESSAGES = {
), None),
0x0422: ("They say that once \x05\x41Morpha's Curse\x05\x40\x01is lifted, striking \x05\x42this stone\x05\x40 can\x01shift the tides of \x05\x44Lake Hylia\x05\x40.\x02", 0x23),
0x401C: ("Please find my dear \05\x41Princess Ruto\x05\x40\x01immediately... Zora!\x12\x68\x7A", 0x23),
0x9100: ("I am out of goods now.\x01Sorry!\x04The mark that will lead you to\x01the Spirit Temple is the \x05\x41flag on\x01the left \x05\x40outside the shop.\x01Be seeing you!\x02", 0x00)
0x9100: ("I am out of goods now.\x01Sorry!\x04The mark that will lead you to\x01the Spirit Temple is the \x05\x41flag on\x01the left \x05\x40outside the shop.\x01Be seeing you!\x02", 0x00),
0x0451: ("\x12\x68\x7AMweep\x07\x04\x52", 0x23),
0x0452: ("\x12\x68\x7AMweep\x07\x04\x53", 0x23),
0x0453: ("\x12\x68\x7AMweep\x07\x04\x54", 0x23),
0x0454: ("\x12\x68\x7AMweep\x07\x04\x55", 0x23),
0x0455: ("\x12\x68\x7AMweep\x07\x04\x56", 0x23),
0x0456: ("\x12\x68\x7AMweep\x07\x04\x57", 0x23),
0x0457: ("\x12\x68\x7AMweep\x07\x04\x58", 0x23),
0x0458: ("\x12\x68\x7AMweep\x07\x04\x59", 0x23),
0x0459: ("\x12\x68\x7AMweep\x07\x04\x5A", 0x23),
0x045A: ("\x12\x68\x7AMweep\x07\x04\x5B", 0x23),
0x045B: ("\x12\x68\x7AMweep", 0x23)
}
@ -359,22 +360,34 @@ def display_code_list(codes):
return message
def encode_text_string(text):
result = []
it = iter(text)
for ch in it:
n = ord(ch)
mapped = CHARACTER_MAP.get(ch)
if mapped:
result.append(mapped)
continue
if n in CONTROL_CODES:
result.append(n)
for _ in range(CONTROL_CODES[n][1]):
result.append(ord(next(it)))
continue
if n in CHARACTER_MAP.values(): # Character has already been translated
result.append(n)
continue
raise ValueError(f"While encoding {text!r}: Unable to translate unicode character {ch!r} ({n}). (Already decoded: {result!r})")
return result
def parse_control_codes(text):
if isinstance(text, list):
bytes = text
elif isinstance(text, bytearray):
bytes = list(text)
else:
bytes = list(text.encode('utf-8'))
# Special characters encoded to utf-8 must be re-encoded to OoT's values for them.
# Tuple is used due to utf-8 encoding using two bytes.
i = 0
while i < len(bytes) - 1:
if (bytes[i], bytes[i+1]) in UTF8_TO_OOT_SPECIAL:
bytes[i] = UTF8_TO_OOT_SPECIAL[(bytes[i], bytes[i+1])]
del bytes[i+1]
i += 1
bytes = encode_text_string(text)
text_codes = []
index = 0
@ -396,8 +409,7 @@ def parse_control_codes(text):
# holds a single character or control code of a string
class Text_Code():
class Text_Code:
def display(self):
if self.code in CONTROL_CODES:
return CONTROL_CODES[self.code][2](self.data)
@ -434,7 +446,8 @@ class Text_Code():
ret = chr(self.code) + ret
return ret
else:
return chr(self.code)
# raise ValueError(repr(REVERSE_MAP))
return REVERSE_MAP[self.code]
# writes the code to the given offset, and returns the offset of the next byte
def size(self):
@ -465,16 +478,18 @@ class Text_Code():
__str__ = __repr__ = display
# holds a single message, and all its data
class Message():
# holds a single message, and all its data
class Message:
def display(self):
meta_data = ["#" + str(self.index),
meta_data = [
"#" + str(self.index),
"ID: 0x" + "{:04x}".format(self.id),
"Offset: 0x" + "{:06x}".format(self.offset),
"Length: 0x" + "{:04x}".format(self.unpadded_length) + "/0x" + "{:04x}".format(self.length),
"Box Type: " + str(self.box_type),
"Postion: " + str(self.position)]
"Postion: " + str(self.position)
]
return ', '.join(meta_data) + '\n' + self.text
def get_python_string(self):
@ -485,14 +500,17 @@ class Message():
# check if this is an unused message that just contains it's own id as text
def is_id_message(self):
if self.unpadded_length == 5:
if self.unpadded_length != 5:
return False
for i in range(4):
code = self.text_codes[i].code
if not (code in range(ord('0'),ord('9')+1) or code in range(ord('A'),ord('F')+1) or code in range(ord('a'),ord('f')+1) ):
if not (
code in range(ord('0'), ord('9')+1)
or code in range(ord('A'), ord('F')+1)
or code in range(ord('a'), ord('f')+1)
):
return False
return True
return False
def parse_text(self):
self.text_codes = parse_control_codes(self.raw_text)
@ -527,7 +545,6 @@ class Message():
def is_basic(self):
return not (self.has_goto or self.has_keep_open or self.has_event or self.has_fade or self.has_ocarina or self.has_two_choice or self.has_three_choice)
# computes the size of a message, including padding
def size(self):
size = 0
@ -541,16 +558,17 @@ class Message():
# applies whatever transformations we want to the dialogs
def transform(self, replace_ending=False, ending=None, always_allow_skip=True, speed_up_text=True):
ending_codes = [0x02, 0x07, 0x0A, 0x0B, 0x0E, 0x10]
box_breaks = [0x04, 0x0C]
slows_text = [0x08, 0x09, 0x14]
slow_icons = [0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x04, 0x02]
text_codes = []
instant_text_code = Text_Code(0x08, 0)
# # speed the text
if speed_up_text:
text_codes.append(Text_Code(0x08, 0)) # allow instant
text_codes.append(instant_text_code) # allow instant
# write the message
for code in self.text_codes:
@ -566,14 +584,19 @@ class Message():
elif speed_up_text and code.code in box_breaks:
# some special cases for text that needs to be on a timer
if (self.id == 0x605A or # twinrova transformation
self.id == 0x706C or # raru ending text
self.id == 0x706C or # rauru ending text
self.id == 0x70DD or # ganondorf ending text
self.id == 0x7070): # zelda ending text
self.id in (0x706F, 0x7091, 0x7092, 0x7093, 0x7094, 0x7095, 0x7070) # zelda ending text
):
text_codes.append(code)
text_codes.append(Text_Code(0x08, 0)) # allow instant
text_codes.append(instant_text_code) # allow instant
else:
text_codes.append(Text_Code(0x04, 0)) # un-delayed break
text_codes.append(Text_Code(0x08, 0)) # allow instant
text_codes.append(instant_text_code) # allow instant
elif speed_up_text and code.code == 0x13 and code.data in slow_icons:
text_codes.append(code)
text_codes.pop(find_last(text_codes, instant_text_code)) # remove last instance of instant text
text_codes.append(instant_text_code) # allow instant
else:
text_codes.append(code)
@ -586,11 +609,9 @@ class Message():
self.text_codes = text_codes
# writes a Message back into the rom, using the given index and offset to update the table
# returns the offset of the next message
def write(self, rom, index, offset):
# construct the table entry
id_bytes = int_to_bytes(self.id, 2)
offset_bytes = int_to_bytes(offset, 3)
@ -609,7 +630,6 @@ class Message():
def __init__(self, raw_text, index, id, opts, offset, length):
self.raw_text = raw_text
self.index = index
@ -634,7 +654,6 @@ class Message():
# read a single message from rom
@classmethod
def from_rom(cls, rom, index):
entry_offset = ENG_TABLE_START + 8 * index
entry = rom.read_bytes(entry_offset, 8)
next = rom.read_bytes(entry_offset + 8, 8)
@ -650,19 +669,7 @@ class Message():
@classmethod
def from_string(cls, text, id=0, opts=0x00):
bytes = list(text.encode('utf-8')) + [0x02]
# Clean up garbage values added when encoding special characters again.
bytes = list(filter(lambda a: a != 194, bytes)) # 0xC2 added before each accent char.
i = 0
while i < len(bytes) - 1:
if bytes[i] in SPECIAL_CHARACTERS and bytes[i] not in UTF8_TO_OOT_SPECIAL.values(): # This indicates it's one of the button chars (A button, etc).
# Have to delete 2 inserted garbage values.
del bytes[i-1]
del bytes[i-2]
i -= 2
i+= 1
bytes = text + "\x02"
return cls(bytes, 0, id, opts, 0, len(bytes) + 1)
@classmethod
@ -872,7 +879,7 @@ def make_player_message(text):
wrapped_text = line_wrap(new_text, False, False, False)
if wrapped_text != new_text:
new_text = line_wrap(new_text, True, True, False)
new_text = line_wrap(new_text, True, False, False)
return new_text
@ -882,7 +889,7 @@ def make_player_message(text):
def update_item_messages(messages, world):
new_item_messages = {**ITEM_MESSAGES, **KEYSANITY_MESSAGES}
for id, text in new_item_messages.items():
if len(world.multiworld.worlds) > 1:
if world.multiworld.players > 1:
update_message_by_id(messages, id, make_player_message(text), 0x23)
else:
update_message_by_id(messages, id, text, 0x23)
@ -968,7 +975,9 @@ def shuffle_messages(messages, except_hints=True, always_allow_skip=True):
def is_exempt(m):
hint_ids = (
GOSSIP_STONE_MESSAGES + TEMPLE_HINTS_MESSAGES + LIGHT_ARROW_HINT +
GOSSIP_STONE_MESSAGES + TEMPLE_HINTS_MESSAGES +
[data['id'] for data in misc_item_hint_table.values()] +
[data['id'] for data in misc_location_hint_table.values()] +
list(KEYSANITY_MESSAGES.keys()) + shuffle_messages.shop_item_messages +
shuffle_messages.scrubs_message_ids +
[0x5036, 0x70F5] # Chicken count and poe count respectively
@ -1009,7 +1018,9 @@ def shuffle_messages(messages, except_hints=True, always_allow_skip=True):
return permutation
# Update warp song text boxes for ER
def update_warp_song_text(messages, ootworld):
def update_warp_song_text(messages, world):
from .Hints import HintArea
msg_list = {
0x088D: 'Minuet of Forest Warp -> Sacred Forest Meadow',
0x088E: 'Bolero of Fire Warp -> DMC Central Local',
@ -1019,18 +1030,17 @@ def update_warp_song_text(messages, ootworld):
0x0892: 'Prelude of Light Warp -> Temple of Time',
}
if world.logic_rules != "glitched": # Entrances not set on glitched logic so following code will error
for id, entr in msg_list.items():
destination = ootworld.multiworld.get_entrance(entr, ootworld.player).connected_region
if destination.pretty_name:
destination_name = destination.pretty_name
elif destination.hint_text:
destination_name = destination.hint_text
elif destination.dungeon:
destination_name = destination.dungeon.hint
if 'warp_songs' in world.misc_hints or not world.warp_songs:
destination = world.get_entrance(entr).connected_region
destination_name = HintArea.at(destination)
color = COLOR_MAP[destination_name.color]
if destination_name.preposition(True) is not None:
destination_name = f'to {destination_name}'
else:
destination_name = destination.name
color = COLOR_MAP[destination.font_color or 'White']
destination_name = 'to a mysterious place'
color = COLOR_MAP['White']
new_msg = f"\x08\x05{color}Warp to {destination_name}?\x05\40\x09\x01\x01\x1b\x05{color}OK\x01No\x05\40"
new_msg = f"\x08\x05{color}Warp {destination_name}?\x05\40\x09\x01\x01\x1b\x05\x42OK\x01No\x05\40"
update_message_by_id(messages, id, new_msg)

View File

@ -88,7 +88,7 @@ def write_block_section(start, key_skip, in_data, patch_data, is_continue):
# xor_range is the range the XOR key will read from. This range is not
# too important, but I tried to choose from a section that didn't really
# have big gaps of 0s which we want to avoid.
def create_patch_file(rom, file, xor_range=(0x00B8AD30, 0x00F029A0)):
def create_patch_file(rom, xor_range=(0x00B8AD30, 0x00F029A0)):
dma_start, dma_end = rom.get_dma_table_range()
# add header
@ -169,9 +169,7 @@ def create_patch_file(rom, file, xor_range=(0x00B8AD30, 0x00F029A0)):
patch_data = bytes(patch_data.buffer)
patch_data = zlib.compress(patch_data)
# save the patch file
with open(file, 'wb') as outfile:
outfile.write(patch_data)
return patch_data
# This will apply a patch file to a source rom to generate a patched rom.

View File

@ -1,6 +1,6 @@
import typing
import random
from Options import Option, DefaultOnToggle, Toggle, Range, OptionList, DeathLink
from Options import Option, DefaultOnToggle, Toggle, Range, OptionList, OptionSet, DeathLink
from .LogicTricks import normalized_name_tricks
from .ColorSFXOptions import *
@ -92,6 +92,7 @@ class Bridge(Choice):
option_medallions = 3
option_dungeons = 4
option_tokens = 5
option_hearts = 6
default = 3
@ -135,9 +136,21 @@ class GrottoEntrances(Toggle):
display_name = "Shuffle Grotto/Grave Entrances"
class DungeonEntrances(Toggle):
"""Shuffles dungeon entrances, excluding Ganon's Castle. Opens Deku, Fire and BotW to both ages."""
class DungeonEntrances(Choice):
"""Shuffles dungeon entrances. Opens Deku, Fire and BotW to both ages. "All" includes Ganon's Castle."""
display_name = "Shuffle Dungeon Entrances"
option_off = 0
option_simple = 1
option_all = 2
alias_true = 1
class BossEntrances(Choice):
"""Shuffles boss entrances. "Limited" prevents age-mixing of bosses."""
display_name = "Shuffle Boss Entrances"
option_off = 0
option_limited = 1
option_full = 2
class OverworldEntrances(Toggle):
@ -155,9 +168,14 @@ class WarpSongs(Toggle):
display_name = "Randomize Warp Songs"
class SpawnPositions(Toggle):
class SpawnPositions(Choice):
"""Randomizes the starting position on loading a save. Consistent between savewarps."""
display_name = "Randomize Spawn Positions"
option_off = 0
option_child = 1
option_adult = 2
option_both = 3
alias_true = 3
class MixEntrancePools(Choice):
@ -203,14 +221,96 @@ class LogicalChus(Toggle):
display_name = "Bombchus Considered in Logic"
class MQDungeons(TrackRandomRange):
"""Number of MQ dungeons. The dungeons to replace are randomly selected."""
display_name = "Number of MQ Dungeons"
class DungeonShortcuts(Choice):
"""Shortcuts to dungeon bosses are available without any requirements."""
display_name = "Dungeon Boss Shortcuts Mode"
option_off = 0
option_choice = 1
option_all = 2
option_random_dungeons = 3
class DungeonShortcutsList(OptionSet):
"""Chosen dungeons to have shortcuts."""
display_name = "Shortcut Dungeons"
valid_keys = {
"Deku Tree",
"Dodongo's Cavern",
"Jabu Jabu's Belly",
"Forest Temple",
"Fire Temple",
"Water Temple",
"Shadow Temple",
"Spirit Temple",
}
class MQDungeons(Choice):
"""Choose between vanilla and Master Quest dungeon layouts."""
display_name = "MQ Dungeon Mode"
option_vanilla = 0
option_mq = 1
option_specific = 2
option_count = 3
class MQDungeonList(OptionSet):
"""Chosen dungeons to be MQ layout."""
display_name = "MQ Dungeon List"
valid_keys = {
"Deku Tree",
"Dodongo's Cavern",
"Jabu Jabu's Belly",
"Forest Temple",
"Fire Temple",
"Water Temple",
"Shadow Temple",
"Spirit Temple",
"Bottom of the Well",
"Ice Cavern",
"Gerudo Training Ground",
"Ganon's Castle",
}
class MQDungeonCount(TrackRandomRange):
"""Number of MQ dungeons, chosen randomly."""
display_name = "MQ Dungeon Count"
range_start = 0
range_end = 12
default = 0
class EmptyDungeons(Choice):
"""Pre-completed dungeons are barren and rewards are given for free."""
display_name = "Pre-completed Dungeons Mode"
option_none = 0
option_specific = 1
option_count = 2
class EmptyDungeonList(OptionSet):
"""Chosen dungeons to be pre-completed."""
display_name = "Pre-completed Dungeon List"
valid_keys = {
"Deku Tree",
"Dodongo's Cavern",
"Jabu Jabu's Belly",
"Forest Temple",
"Fire Temple",
"Water Temple",
"Shadow Temple",
"Spirit Temple",
}
class EmptyDungeonCount(Range):
display_name = "Pre-completed Dungeon Count"
range_start = 1
range_end = 8
default = 2
world_options: typing.Dict[str, type(Option)] = {
"starting_age": StartingAge,
"shuffle_interior_entrances": InteriorEntrances,
@ -220,65 +320,76 @@ world_options: typing.Dict[str, type(Option)] = {
"owl_drops": OwlDrops,
"warp_songs": WarpSongs,
"spawn_positions": SpawnPositions,
"shuffle_bosses": BossEntrances,
# "mix_entrance_pools": MixEntrancePools,
# "decouple_entrances": DecoupleEntrances,
"triforce_hunt": TriforceHunt,
"triforce_goal": TriforceGoal,
"extra_triforce_percentage": ExtraTriforces,
"bombchus_in_logic": LogicalChus,
"mq_dungeons": MQDungeons,
"dungeon_shortcuts": DungeonShortcuts,
"dungeon_shortcuts_list": DungeonShortcutsList,
"mq_dungeons_mode": MQDungeons,
"mq_dungeons_list": MQDungeonList,
"mq_dungeons_count": MQDungeonCount,
# "empty_dungeons_mode": EmptyDungeons,
# "empty_dungeons_list": EmptyDungeonList,
# "empty_dungeon_count": EmptyDungeonCount,
}
class LacsCondition(Choice):
"""Set the requirements for the Light Arrow Cutscene in the Temple of Time."""
display_name = "Light Arrow Cutscene Requirement"
option_vanilla = 0
option_stones = 1
option_medallions = 2
option_dungeons = 3
option_tokens = 4
# class LacsCondition(Choice):
# """Set the requirements for the Light Arrow Cutscene in the Temple of Time."""
# display_name = "Light Arrow Cutscene Requirement"
# option_vanilla = 0
# option_stones = 1
# option_medallions = 2
# option_dungeons = 3
# option_tokens = 4
class LacsStones(Range):
"""Set the number of Spiritual Stones required for LACS."""
display_name = "Spiritual Stones Required for LACS"
range_start = 0
range_end = 3
default = 3
# class LacsStones(Range):
# """Set the number of Spiritual Stones required for LACS."""
# display_name = "Spiritual Stones Required for LACS"
# range_start = 0
# range_end = 3
# default = 3
class LacsMedallions(Range):
"""Set the number of medallions required for LACS."""
display_name = "Medallions Required for LACS"
range_start = 0
range_end = 6
default = 6
# class LacsMedallions(Range):
# """Set the number of medallions required for LACS."""
# display_name = "Medallions Required for LACS"
# range_start = 0
# range_end = 6
# default = 6
class LacsRewards(Range):
"""Set the number of dungeon rewards required for LACS."""
display_name = "Dungeon Rewards Required for LACS"
range_start = 0
range_end = 9
default = 9
# class LacsRewards(Range):
# """Set the number of dungeon rewards required for LACS."""
# display_name = "Dungeon Rewards Required for LACS"
# range_start = 0
# range_end = 9
# default = 9
class LacsTokens(Range):
"""Set the number of Gold Skulltula Tokens required for LACS."""
display_name = "Tokens Required for LACS"
range_start = 0
range_end = 100
default = 40
# class LacsTokens(Range):
# """Set the number of Gold Skulltula Tokens required for LACS."""
# display_name = "Tokens Required for LACS"
# range_start = 0
# range_end = 100
# default = 40
lacs_options: typing.Dict[str, type(Option)] = {
"lacs_condition": LacsCondition,
"lacs_stones": LacsStones,
"lacs_medallions": LacsMedallions,
"lacs_rewards": LacsRewards,
"lacs_tokens": LacsTokens,
}
# lacs_options: typing.Dict[str, type(Option)] = {
# "lacs_condition": LacsCondition,
# "lacs_stones": LacsStones,
# "lacs_medallions": LacsMedallions,
# "lacs_rewards": LacsRewards,
# "lacs_tokens": LacsTokens,
# }
class BridgeStones(Range):
@ -313,11 +424,20 @@ class BridgeTokens(Range):
default = 40
class BridgeHearts(Range):
"""Set the number of hearts required for the rainbow bridge."""
display_name = "Hearts Required for Bridge"
range_start = 4
range_end = 20
default = 20
bridge_options: typing.Dict[str, type(Option)] = {
"bridge_stones": BridgeStones,
"bridge_medallions": BridgeMedallions,
"bridge_rewards": BridgeRewards,
"bridge_tokens": BridgeTokens,
"bridge_hearts": BridgeHearts,
}
@ -346,6 +466,17 @@ class ShopSlots(Range):
range_end = 4
class ShopPrices(Choice):
"""Controls prices of shop items. "Normal" is a distribution from 0 to 300. "X Wallet" requires that wallet at max. "Affordable" is always 10 rupees."""
display_name = "Shopsanity Prices"
option_normal = 0
option_affordable = 1
option_starting_wallet = 2
option_adults_wallet = 3
option_giants_wallet = 4
option_tycoons_wallet = 5
class TokenShuffle(Choice):
"""Token rewards from Gold Skulltulas are shuffled into the pool."""
display_name = "Tokensanity"
@ -381,9 +512,14 @@ class ShuffleOcarinas(Toggle):
display_name = "Shuffle Ocarinas"
class ShuffleEgg(Toggle):
"""Shuffle the Weird Egg from Malon at Hyrule Castle."""
display_name = "Shuffle Weird Egg"
class ShuffleChildTrade(Choice):
"""Controls the behavior of the start of the child trade quest."""
display_name = "Shuffle Child Trade Item"
option_vanilla = 0
option_shuffle = 1
option_skip_child_zelda = 2
alias_false = 0
alias_true = 1
class ShuffleCard(Toggle):
@ -401,19 +537,62 @@ class ShuffleMedigoronCarpet(Toggle):
display_name = "Shuffle Medigoron & Carpet Salesman"
class ShuffleFreestanding(Choice):
"""Shuffles freestanding rupees, recovery hearts, Shadow Temple Spinning Pots, and Goron Pot."""
display_name = "Shuffle Rupees & Hearts"
option_off = 0
option_all = 1
option_overworld = 2
option_dungeons = 3
class ShufflePots(Choice):
"""Shuffles pots and flying pots which normally contain an item."""
display_name = "Shuffle Pots"
option_off = 0
option_all = 1
option_overworld = 2
option_dungeons = 3
class ShuffleCrates(Choice):
"""Shuffles large and small crates containing an item."""
display_name = "Shuffle Crates"
option_off = 0
option_all = 1
option_overworld = 2
option_dungeons = 3
class ShuffleBeehives(Toggle):
"""Beehives drop an item when destroyed by an explosion, the Hookshot, or the Boomerang."""
display_name = "Shuffle Beehives"
class ShuffleFrogRupees(Toggle):
"""Shuffles the purple rupees received from the Zora's River frogs."""
display_name = "Shuffle Frog Song Rupees"
shuffle_options: typing.Dict[str, type(Option)] = {
"shuffle_song_items": SongShuffle,
"shopsanity": ShopShuffle,
"shop_slots": ShopSlots,
"shopsanity_prices": ShopPrices,
"tokensanity": TokenShuffle,
"shuffle_scrubs": ScrubShuffle,
"shuffle_child_trade": ShuffleChildTrade,
"shuffle_freestanding_items": ShuffleFreestanding,
"shuffle_pots": ShufflePots,
"shuffle_crates": ShuffleCrates,
"shuffle_cows": ShuffleCows,
"shuffle_beehives": ShuffleBeehives,
"shuffle_kokiri_sword": ShuffleSword,
"shuffle_ocarinas": ShuffleOcarinas,
"shuffle_weird_egg": ShuffleEgg,
"shuffle_gerudo_card": ShuffleCard,
"shuffle_beans": ShuffleBeans,
"shuffle_medigoron_carpet_salesman": ShuffleMedigoronCarpet,
"shuffle_frog_song_rupees": ShuffleFrogRupees,
}
@ -427,6 +606,7 @@ class ShuffleMapCompass(Choice):
option_overworld = 4
option_any_dungeon = 5
option_keysanity = 6
option_regional = 7
default = 1
alias_anywhere = 6
@ -440,6 +620,7 @@ class ShuffleKeys(Choice):
option_overworld = 4
option_any_dungeon = 5
option_keysanity = 6
option_regional = 7
default = 3
alias_keysy = 0
alias_anywhere = 6
@ -452,6 +633,7 @@ class ShuffleGerudoKeys(Choice):
option_overworld = 1
option_any_dungeon = 2
option_keysanity = 3
option_regional = 4
alias_anywhere = 3
@ -464,13 +646,14 @@ class ShuffleBossKeys(Choice):
option_overworld = 4
option_any_dungeon = 5
option_keysanity = 6
option_regional = 7
default = 3
alias_keysy = 0
alias_anywhere = 6
class ShuffleGanonBK(Choice):
"""Control where to shuffle the Ganon's Castle Boss Key."""
"""Control how to shuffle the Ganon's Castle Boss Key."""
display_name = "Ganon's Boss Key"
option_remove = 0
option_vanilla = 2
@ -479,6 +662,12 @@ class ShuffleGanonBK(Choice):
option_any_dungeon = 5
option_keysanity = 6
option_on_lacs = 7
option_regional = 8
option_stones = 9
option_medallions = 10
option_dungeons = 11
option_tokens = 12
option_hearts = 13
default = 0
alias_keysy = 0
alias_anywhere = 6
@ -489,19 +678,86 @@ class EnhanceMC(Toggle):
display_name = "Maps and Compasses Give Information"
dungeon_items_options: typing.Dict[str, type(Option)] = {
"shuffle_mapcompass": ShuffleMapCompass,
"shuffle_smallkeys": ShuffleKeys,
"shuffle_fortresskeys": ShuffleGerudoKeys,
"shuffle_bosskeys": ShuffleBossKeys,
"shuffle_ganon_bosskey": ShuffleGanonBK,
"enhance_map_compass": EnhanceMC,
class GanonBKMedallions(Range):
"""Set how many medallions are required to receive Ganon BK."""
display_name = "Medallions Required for Ganon's BK"
range_start = 1
range_end = 6
default = 6
class GanonBKStones(Range):
"""Set how many Spiritual Stones are required to receive Ganon BK."""
display_name = "Spiritual Stones Required for Ganon's BK"
range_start = 1
range_end = 3
default = 3
class GanonBKRewards(Range):
"""Set how many dungeon rewards are required to receive Ganon BK."""
display_name = "Dungeon Rewards Required for Ganon's BK"
range_start = 1
range_end = 9
default = 9
class GanonBKTokens(Range):
"""Set how many Gold Skulltula Tokens are required to receive Ganon BK."""
display_name = "Tokens Required for Ganon's BK"
range_start = 1
range_end = 100
default = 40
class GanonBKHearts(Range):
"""Set how many hearts are required to receive Ganon BK."""
display_name = "Hearts Required for Ganon's BK"
range_start = 4
range_end = 20
default = 20
class KeyRings(Choice):
"""Dungeons have all small keys found at once, rather than individually."""
display_name = "Key Rings Mode"
option_off = 0
option_choose = 1
option_all = 2
option_random_dungeons = 3
class KeyRingList(OptionSet):
"""Select areas with keyrings rather than individual small keys."""
display_name = "Key Ring Areas"
valid_keys = {
"Thieves' Hideout",
"Forest Temple",
"Fire Temple",
"Water Temple",
"Shadow Temple",
"Spirit Temple",
"Bottom of the Well",
"Gerudo Training Ground",
"Ganon's Castle"
}
class SkipChildZelda(Toggle):
"""Game starts with Zelda's Letter, the item at Zelda's Lullaby, and the relevant events already completed."""
display_name = "Skip Child Zelda"
dungeon_items_options: typing.Dict[str, type(Option)] = {
"shuffle_mapcompass": ShuffleMapCompass,
"shuffle_smallkeys": ShuffleKeys,
"shuffle_hideoutkeys": ShuffleGerudoKeys,
"shuffle_bosskeys": ShuffleBossKeys,
"enhance_map_compass": EnhanceMC,
"shuffle_ganon_bosskey": ShuffleGanonBK,
"ganon_bosskey_medallions": GanonBKMedallions,
"ganon_bosskey_stones": GanonBKStones,
"ganon_bosskey_rewards": GanonBKRewards,
"ganon_bosskey_tokens": GanonBKTokens,
"ganon_bosskey_hearts": GanonBKHearts,
"key_rings": KeyRings,
"key_rings_list": KeyRingList,
}
class SkipEscape(DefaultOnToggle):
@ -550,6 +806,11 @@ class FastBunny(Toggle):
display_name = "Fast Bunny Hood"
class PlantBeans(Toggle):
"""Pre-plants all 10 magic beans in the soft soil spots."""
display_name = "Plant Magic Beans"
class ChickenCount(Range):
"""Controls the number of Cuccos for Anju to give an item as child."""
display_name = "Cucco Count"
@ -566,8 +827,15 @@ class BigPoeCount(Range):
default = 1
class FAETorchCount(Range):
"""Number of lit torches required to open Shadow Temple."""
display_name = "Fire Arrow Entry Torch Count"
range_start = 1
range_end = 24
default = 24
timesavers_options: typing.Dict[str, type(Option)] = {
"skip_child_zelda": SkipChildZelda,
"no_escape_sequence": SkipEscape,
"no_guard_stealth": SkipStealth,
"no_epona_race": SkipEponaRace,
@ -577,14 +845,38 @@ timesavers_options: typing.Dict[str, type(Option)] = {
"fast_chests": FastChests,
"free_scarecrow": FreeScarecrow,
"fast_bunny_hood": FastBunny,
"plant_beans": PlantBeans,
"chicken_count": ChickenCount,
"big_poe_count": BigPoeCount,
"fae_torch_count": FAETorchCount,
}
class CSMC(Toggle):
"""Changes chests containing progression into large chests, and nonprogression into small chests."""
display_name = "Chest Size Matches Contents"
class CorrectChestAppearance(Choice):
"""Changes chest textures and/or sizes to match their contents. "Classic" is the old behavior of CSMC."""
display_name = "Chest Appearance Matches Contents"
option_off = 0
option_textures = 1
option_both = 2
option_classic = 3
class MinorInMajor(Toggle):
"""Hylian Shield, Deku Shield, and Bombchus appear in big/gold chests."""
display_name = "Minor Items in Big/Gold Chests"
class InvisibleChests(Toggle):
"""Chests visible only with Lens of Truth. Logic is not changed."""
display_name = "Invisible Chests"
class CorrectPotCrateAppearance(Choice):
"""Unchecked pots and crates have a different texture; unchecked beehives will wiggle. With textures_content, pots and crates have an appearance based on their contents; with textures_unchecked, all unchecked pots/crates have the same appearance."""
display_name = "Pot, Crate, and Beehive Appearance"
option_off = 0
option_textures_content = 1
option_textures_unchecked = 2
class Hints(Choice):
@ -598,7 +890,7 @@ class Hints(Choice):
class MiscHints(DefaultOnToggle):
"""Controls whether the Temple of Time altar gives dungeon prize info and whether Ganondorf hints the Light Arrows."""
"""The Temple of Time altar hints dungeon rewards, bridge info, and Ganon BK info; Ganondorf hints the Light Arrows; Dampe's diary hints a local Hookshot if one exists; Skulltula House locations hint their item."""
display_name = "Misc Hints"
@ -608,7 +900,7 @@ class HintDistribution(Choice):
option_balanced = 0
option_ddr = 1
option_league = 2
option_mw2 = 3
option_mw3 = 3
option_scrubs = 4
option_strong = 5
option_tournament = 6
@ -637,6 +929,17 @@ class DamageMultiplier(Choice):
default = 1
class DeadlyBonks(Choice):
"""Bonking on a wall or object will hurt Link. "Normal" is a half heart of damage."""
display_name = "Bonks Do Damage"
option_none = 0
option_half = 1
option_normal = 2
option_double = 3
option_quadruple = 4
option_ohko = 5
class HeroMode(Toggle):
"""Hearts will not drop from enemies or objects."""
display_name = "Hero Mode"
@ -656,6 +959,16 @@ class StartingToD(Choice):
option_witching_hour = 8
class BlueFireArrows(Toggle):
"""Ice arrows can melt red ice and break the mud walls in Dodongo's Cavern."""
display_name = "Blue Fire Arrows"
class FixBrokenDrops(Toggle):
"""Fixes two broken vanilla drops: deku shield in child Spirit Temple, and magic drop on GTG eye statue."""
display_name = "Fix Broken Drops"
class ConsumableStart(Toggle):
"""Start the game with full Deku Sticks and Deku Nuts."""
display_name = "Start with Consumables"
@ -667,14 +980,20 @@ class RupeeStart(Toggle):
misc_options: typing.Dict[str, type(Option)] = {
"correct_chest_sizes": CSMC,
"correct_chest_appearances": CorrectChestAppearance,
"minor_items_as_major_chest": MinorInMajor,
"invisible_chests": InvisibleChests,
"correct_potcrate_appearances": CorrectPotCrateAppearance,
"hints": Hints,
"misc_hints": MiscHints,
"hint_dist": HintDistribution,
"text_shuffle": TextShuffle,
"damage_multiplier": DamageMultiplier,
"deadly_bonks": DeadlyBonks,
"no_collectible_hearts": HeroMode,
"starting_tod": StartingToD,
"blue_fire_arrows": BlueFireArrows,
"fix_broken_drops": FixBrokenDrops,
"start_with_consumables": ConsumableStart,
"start_with_rupees": RupeeStart,
}
@ -709,37 +1028,29 @@ class IceTrapVisual(Choice):
option_anything = 2
class AdultTradeItem(Choice):
option_pocket_egg = 0
option_pocket_cucco = 1
option_cojiro = 2
option_odd_mushroom = 3
option_poachers_saw = 4
option_broken_sword = 5
option_prescription = 6
option_eyeball_frog = 7
option_eyedrops = 8
option_claim_check = 9
class EarlyTradeItem(AdultTradeItem):
"""Earliest item that can appear in the adult trade sequence."""
display_name = "Adult Trade Sequence Earliest Item"
default = 6
class LateTradeItem(AdultTradeItem):
"""Latest item that can appear in the adult trade sequence."""
display_name = "Adult Trade Sequence Latest Item"
default = 9
class AdultTradeStart(OptionSet):
"""Choose the items that can appear to start the adult trade sequence. By default it is Claim Check only."""
display_name = "Adult Trade Sequence Items"
default = {"Claim Check"}
valid_keys = {
"Pocket Egg",
"Pocket Cucco",
"Cojiro",
"Odd Mushroom",
"Poacher's Saw",
"Broken Sword",
"Prescription",
"Eyeball Frog",
"Eyedrops",
"Claim Check",
}
itempool_options: typing.Dict[str, type(Option)] = {
"item_pool_value": ItemPoolValue,
"junk_ice_traps": IceTraps,
"ice_trap_appearance": IceTrapVisual,
"logic_earliest_adult_trade": EarlyTradeItem,
"logic_latest_adult_trade": LateTradeItem,
"adult_trade_start": AdultTradeStart,
}
# Start of cosmetic options
@ -756,6 +1067,11 @@ class DisplayDpad(DefaultOnToggle):
display_name = "Display D-Pad HUD"
class DpadDungeonMenu(DefaultOnToggle):
"""Show separated menus on the pause screen for dungeon keys, rewards, and Vanilla/MQ info."""
display_name = "Display D-Pad Dungeon Info"
class CorrectColors(DefaultOnToggle):
"""Makes in-game models match their HUD element colors."""
display_name = "Item Model Colors Match Cosmetics"
@ -793,6 +1109,7 @@ class SwordTrailDuration(Range):
cosmetic_options: typing.Dict[str, type(Option)] = {
"default_targeting": Targeting,
"display_dpad": DisplayDpad,
"dpad_dungeon_menu": DpadDungeonMenu,
"correct_model_colors": CorrectColors,
"background_music": BackgroundMusic,
"fanfares": Fanfares,
@ -869,7 +1186,7 @@ oot_options: typing.Dict[str, type(Option)] = {
**world_options,
**bridge_options,
**dungeon_items_options,
**lacs_options,
# **lacs_options,
**shuffle_options,
**timesavers_options,
**misc_options,

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
from enum import unique, Enum
from BaseClasses import Region
from .Hints import HintArea
# copied from OoT-Randomizer/Region.py
@ -33,6 +34,8 @@ class OOTRegion(Region):
def __init__(self, name: str, type, hint, player: int):
super(OOTRegion, self).__init__(name, type, hint, player)
self._oot_hint = None
self.alt_hint = None
self.price = None
self.time_passes = False
self.provides_time = TimeOfDay.NONE
@ -40,6 +43,7 @@ class OOTRegion(Region):
self.dungeon = None
self.pretty_name = None
self.font_color = None
self.is_boss_room = False
def get_scene(self):
if self.scene:
@ -61,3 +65,15 @@ class OOTRegion(Region):
else: # we don't care about age
return self in state.child_reachable_regions[self.player] or self in state.adult_reachable_regions[self.player]
def set_hint_data(self, hint):
if self.dungeon:
self._oot_hint = HintArea.for_dungeon(self.dungeon)
else:
self._oot_hint = HintArea[hint]
self.hint_text = str(self._oot_hint)
# This is too generic of a name to risk not breaking in the future.
# This lets us possibly switch it out later if AP starts using it.
@property
def hint(self):
return self._oot_hint

View File

@ -508,3 +508,6 @@ class Rule_AST_Transformer(ast.NodeTransformer):
def can_live_dmg(self, node):
return ast.parse(f"state._oot_can_live_dmg({self.player}, {node.args[0].value})", mode='eval').body
def region_has_shortcuts(self, node):
return ast.parse(f"state._oot_region_has_shortcuts({self.player}, '{node.args[0].value}')", mode='eval').body

View File

@ -1,7 +1,6 @@
from collections import deque
import logging
from .SaveContext import SaveContext
from .Regions import TimeOfDay
from .Items import oot_is_item_of_type
@ -21,9 +20,18 @@ class OOTLogic(LogicMixin):
def _oot_has_dungeon_rewards(self, count, player):
return self.has_group("rewards", player, count)
def _oot_has_hearts(self, count, player):
containers = self.count("Heart Container", player)
pieces = self.count("Piece of Heart", player) + self.count("Piece of Heart (Treasure Chest Game)", player)
total_hearts = 3 + containers + int(pieces / 4)
return total_hearts >= count
def _oot_has_bottle(self, player):
return self.has_group("logic_bottles", player)
def _oot_has_beans(self, player):
return self.has("Magic Bean Pack", player) or self.has("Buy Magic Bean", player) or self.has("Magic Bean", player, 10)
# Used for fall damage and other situations where damage is unavoidable
def _oot_can_live_dmg(self, player, hearts):
mult = self.multiworld.worlds[player].damage_multiplier
@ -32,6 +40,11 @@ class OOTLogic(LogicMixin):
else:
return mult != 'ohko'
# Figure out if the given region's parent dungeon has shortcuts enabled
def _oot_region_has_shortcuts(self, player, regionname):
return self.multiworld.worlds[player].region_has_shortcuts(regionname)
# This function operates by assuming different behavior based on the "level of recursion", handled manually.
# If it's called while self.age[player] is None, then it will set the age variable and then attempt to reach the region.
# If self.age[player] is not None, then it will compare it to the 'age' parameter, and return True iff they are equal.
@ -125,12 +138,14 @@ def set_rules(ootworld):
# is_child = ootworld.parser.parse_rule('is_child')
guarantee_hint = ootworld.parser.parse_rule('guarantee_hint')
for location in filter(lambda location: location.name in ootworld.shop_prices or 'Deku Scrub' in location.name, ootworld.get_locations()):
for location in filter(lambda location: location.name in ootworld.shop_prices
or location.type in {'Scrub', 'GrottoScrub'}, ootworld.get_locations()):
if location.type == 'Shop':
location.price = ootworld.shop_prices[location.name]
add_rule(location, create_shop_rule(location, ootworld.parser))
if ootworld.dungeon_mq['Forest Temple'] and ootworld.shuffle_bosskeys == 'dungeon' and ootworld.shuffle_smallkeys == 'dungeon' and ootworld.tokensanity == 'off':
if (ootworld.dungeon_mq['Forest Temple'] and ootworld.shuffle_bosskeys == 'dungeon'
and ootworld.shuffle_smallkeys == 'dungeon' and ootworld.tokensanity == 'off'):
# First room chest needs to be a small key. Make sure the boss key isn't placed here.
location = world.get_location('Forest Temple MQ First Room Chest', player)
forbid_item(location, 'Boss Key (Forest Temple)', ootworld.player)
@ -141,11 +156,6 @@ def set_rules(ootworld):
location = world.get_location('Sheik in Ice Cavern', player)
add_item_rule(location, lambda item: item.player == player and oot_is_item_of_type(item, 'Song'))
if ootworld.skip_child_zelda:
# If skip child zelda is on, the item at Song from Impa must be giveable by the save context.
location = world.get_location('Song from Impa', player)
add_item_rule(location, lambda item: item.name in SaveContext.giveable_items)
for name in ootworld.always_hints:
add_rule(world.get_location(name, player), guarantee_hint)

View File

@ -1,4 +1,37 @@
from itertools import chain
from enum import IntEnum
from .ItemPool import IGNORE_LOCATION
class Scenes(IntEnum):
# Dungeons
DEKU_TREE = 0x00
DODONGOS_CAVERN = 0x01
KING_DODONGO_LOBBY = 0x12
JABU_JABU = 0x02
FOREST_TEMPLE = 0x03
FIRE_TEMPLE = 0x04
WATER_TEMPLE = 0x05
SPIRIT_TEMPLE = 0x06
SHADOW_TEMPLE = 0x07
# Bean patch scenes
GRAVEYARD = 0x53
ZORAS_RIVER = 0x54
KOKIRI_FOREST = 0x55
LAKE_HYLIA = 0x57
GERUDO_VALLEY = 0x5A
LOST_WOODS = 0x5B
DESERT_COLOSSUS = 0x5C
DEATH_MOUNTAIN_TRAIL = 0x60
DEATH_MOUNTAIN_CRATER = 0x61
class FlagType(IntEnum):
CHEST = 0x00
SWITCH = 0x01
CLEAR = 0x02
COLLECT = 0x03
# 0x04 unused
VISITED_ROOM = 0x05
VISITED_FLOOR = 0x06
class Address():
prev_address = None
@ -156,6 +189,14 @@ class SaveContext():
else:
address.get_writes(self)
def write_permanent_flag(self, scene, type, byte_offset, bit_values):
# Save format is described here: https://wiki.cloudmodding.com/oot/Save_Format
# Permanent flags start at offset 0x00D4. Each scene has 7 types of flags, one
# of which is unused. Each flag type is 4 bytes wide per-scene, thus each scene
# takes 28 (0x1C) bytes.
# Scenes and FlagType enums are defined for increased readability when using
# this function.
self.write_bits(0x00D4 + scene * 0x1C + type * 0x04 + byte_offset, bit_values)
def set_ammo_max(self):
ammo_maxes = {
@ -218,18 +259,16 @@ class SaveContext():
self.addresses['health_capacity'].value = int(health) * 0x10
self.addresses['health'].value = int(health) * 0x10
self.addresses['quest']['heart_pieces'].value = int((health % 1) * 4)
self.addresses['quest']['heart_pieces'].value = int((health % 1) * 4) * 0x10
def give_raw_item(self, item):
def give_item(self, world, item, count=1):
if item.endswith(')'):
item_base, count = item[:-1].split(' (', 1)
if count.isdigit():
return self.give_item(item_base, count=int(count))
return self.give_item(item)
item_base, implicit_count = item[:-1].split(' (', 1)
if implicit_count.isdigit():
item = item_base
count *= int(implicit_count)
def give_item(self, item, count=1):
if item in SaveContext.bottle_types:
self.give_bottle(item, count)
elif item in ["Piece of Heart", "Piece of Heart (Treasure Chest Game)"]:
@ -237,9 +276,53 @@ class SaveContext():
elif item == "Heart Container":
self.give_health(count)
elif item == "Bombchu Item":
self.give_bombchu_item()
self.give_bombchu_item(world)
elif item == IGNORE_LOCATION:
pass # used to disable some skipped and inaccessible locations
elif item in SaveContext.save_writes_table:
for address, value in SaveContext.save_writes_table[item].items():
if item.startswith('Small Key Ring ('):
dungeon = item[:-1].split(' (', 1)[1]
save_writes = {
"Forest Temple" : {
'keys.forest': 6 if world.dungeon_mq[dungeon] else 5,
'total_keys.forest': 6 if world.dungeon_mq[dungeon] else 5,
},
"Fire Temple" : {
'keys.fire': 5 if world.dungeon_mq[dungeon] else 8,
'total_keys.fire': 5 if world.dungeon_mq[dungeon] else 8,
},
"Water Temple" : {
'keys.water': 2 if world.dungeon_mq[dungeon] else 6,
'total_keys.water': 2 if world.dungeon_mq[dungeon] else 6,
},
"Spirit Temple" : {
'keys.spirit': 7 if world.dungeon_mq[dungeon] else 5,
'total_keys.spirit': 7 if world.dungeon_mq[dungeon] else 5,
},
"Shadow Temple" : {
'keys.shadow': 6 if world.dungeon_mq[dungeon] else 5,
'total_keys.shadow': 6 if world.dungeon_mq[dungeon] else 5,
},
"Bottom of the Well" : {
'keys.botw': 2 if world.dungeon_mq[dungeon] else 3,
'total_keys.botw': 2 if world.dungeon_mq[dungeon] else 3,
},
"Gerudo Training Ground" : {
'keys.gtg': 3 if world.dungeon_mq[dungeon] else 9,
'total_keys.gtg': 3 if world.dungeon_mq[dungeon] else 9,
},
"Thieves Hideout" : {
'keys.fortress': 4,
'total_keys.fortress': 4,
},
"Ganons Castle" : {
'keys.gc': 3 if world.dungeon_mq[dungeon] else 2,
'total_keys.gc': 3 if world.dungeon_mq[dungeon] else 2,
},
}[dungeon]
else:
save_writes = SaveContext.save_writes_table[item]
for address, value in save_writes.items():
if value is None:
value = count
elif isinstance(value, list):
@ -269,8 +352,8 @@ class SaveContext():
raise ValueError("Cannot give unknown starting item %s" % item)
def give_bombchu_item(self):
self.give_item("Bombchus", 0)
def give_bombchu_item(self, world):
self.give_item(world, "Bombchus", 0)
def equip_default_items(self, age):
@ -455,7 +538,7 @@ class SaveContext():
'kokiri_sword' : Address(0x009C, size=2, mask=0x0001),
'master_sword' : Address(0x009C, size=2, mask=0x0002),
'biggoron_sword' : Address(0x009C, size=2, mask=0x0004),
'broken_knife' : Address(0x009C, size=2, mask=0x0008),
'broken_giants_knife' : Address(0x009C, size=2, mask=0x0008),
'deku_shield' : Address(0x009C, size=2, mask=0x0010),
'hylian_shield' : Address(0x009C, size=2, mask=0x0020),
'mirror_shield' : Address(0x009C, size=2, mask=0x0040),
@ -610,7 +693,24 @@ class SaveContext():
},
'defense_hearts' : Address(size=1, max=20),
'gs_tokens' : Address(size=2, max=100),
'total_keys' : { # Upper half of unused word in own scene
'deku' : Address(0xD4 + 0x1C * 0x00 + 0x10, size=2),
'dodongo' : Address(0xD4 + 0x1C * 0x01 + 0x10, size=2),
'jabu' : Address(0xD4 + 0x1C * 0x02 + 0x10, size=2),
'forest' : Address(0xD4 + 0x1C * 0x03 + 0x10, size=2),
'fire' : Address(0xD4 + 0x1C * 0x04 + 0x10, size=2),
'water' : Address(0xD4 + 0x1C * 0x05 + 0x10, size=2),
'spirit' : Address(0xD4 + 0x1C * 0x06 + 0x10, size=2),
'shadow' : Address(0xD4 + 0x1C * 0x07 + 0x10, size=2),
'botw' : Address(0xD4 + 0x1C * 0x08 + 0x10, size=2),
'ice' : Address(0xD4 + 0x1C * 0x09 + 0x10, size=2),
'gt' : Address(0xD4 + 0x1C * 0x0A + 0x10, size=2),
'gtg' : Address(0xD4 + 0x1C * 0x0B + 0x10, size=2),
'fortress' : Address(0xD4 + 0x1C * 0x0C + 0x10, size=2),
'gc' : Address(0xD4 + 0x1C * 0x0D + 0x10, size=2),
},
'triforce_pieces' : Address(0xD4 + 0x1C * 0x48 + 0x10, size=4), # Unused word in scene x48
'pending_freezes' : Address(0xD4 + 0x1C * 0x49 + 0x10, size=4), # Unused word in scene x49
}
@ -667,7 +767,7 @@ class SaveContext():
'odd_mushroom' : 0x30,
'odd_potion' : 0x31,
'poachers_saw' : 0x32,
'broken_gorons_sword' : 0x33,
'broken_sword' : 0x33,
'prescription' : 0x34,
'eyeball_frog' : 0x35,
'eye_drops' : 0x36,
@ -789,6 +889,11 @@ class SaveContext():
'item_slot.stick' : 'stick',
'upgrades.stick_upgrade' : [2,3],
},
"Deku Stick": {
'item_slot.stick' : 'stick',
'upgrades.stick_upgrade' : 1,
'ammo.stick' : None,
},
"Deku Sticks": {
'item_slot.stick' : 'stick',
'upgrades.stick_upgrade' : 1,
@ -849,7 +954,7 @@ class SaveContext():
"Cojiro" : {'item_slot.adult_trade' : 'cojiro'},
"Odd Mushroom" : {'item_slot.adult_trade' : 'odd_mushroom'},
"Poachers Saw" : {'item_slot.adult_trade' : 'poachers_saw'},
"Broken Sword" : {'item_slot.adult_trade' : 'broken_knife'},
"Broken Sword" : {'item_slot.adult_trade' : 'broken_sword'},
"Prescription" : {'item_slot.adult_trade' : 'prescription'},
"Eyeball Frog" : {'item_slot.adult_trade' : 'eyeball_frog'},
"Eyedrops" : {'item_slot.adult_trade' : 'eye_drops'},
@ -916,17 +1021,116 @@ class SaveContext():
'double_magic' : [False, True],
},
"Rupee" : {'rupees' : None},
"Rupee (Treasure Chest Game)" : {'rupees' : None},
"Rupees" : {'rupees' : None},
"Magic Bean Pack" : {
'item_slot.beans' : 'beans',
'ammo.beans' : 10
},
"Ice Trap" : {'pending_freezes': None},
"Triforce Piece" : {'triforce_pieces': None},
"Boss Key (Forest Temple)" : {'dungeon_items.forest.boss_key': True},
"Boss Key (Fire Temple)" : {'dungeon_items.fire.boss_key': True},
"Boss Key (Water Temple)" : {'dungeon_items.water.boss_key': True},
"Boss Key (Spirit Temple)" : {'dungeon_items.spirit.boss_key': True},
"Boss Key (Shadow Temple)" : {'dungeon_items.shadow.boss_key': True},
"Boss Key (Ganons Castle)" : {'dungeon_items.gt.boss_key': True},
"Compass (Deku Tree)" : {'dungeon_items.deku.compass': True},
"Compass (Dodongos Cavern)" : {'dungeon_items.dodongo.compass': True},
"Compass (Jabu Jabus Belly)" : {'dungeon_items.jabu.compass': True},
"Compass (Forest Temple)" : {'dungeon_items.forest.compass': True},
"Compass (Fire Temple)" : {'dungeon_items.fire.compass': True},
"Compass (Water Temple)" : {'dungeon_items.water.compass': True},
"Compass (Spirit Temple)" : {'dungeon_items.spirit.compass': True},
"Compass (Shadow Temple)" : {'dungeon_items.shadow.compass': True},
"Compass (Bottom of the Well)" : {'dungeon_items.botw.compass': True},
"Compass (Ice Cavern)" : {'dungeon_items.ice.compass': True},
"Map (Deku Tree)" : {'dungeon_items.deku.map': True},
"Map (Dodongos Cavern)" : {'dungeon_items.dodongo.map': True},
"Map (Jabu Jabus Belly)" : {'dungeon_items.jabu.map': True},
"Map (Forest Temple)" : {'dungeon_items.forest.map': True},
"Map (Fire Temple)" : {'dungeon_items.fire.map': True},
"Map (Water Temple)" : {'dungeon_items.water.map': True},
"Map (Spirit Temple)" : {'dungeon_items.spirit.map': True},
"Map (Shadow Temple)" : {'dungeon_items.shadow.map': True},
"Map (Bottom of the Well)" : {'dungeon_items.botw.map': True},
"Map (Ice Cavern)" : {'dungeon_items.ice.map': True},
"Small Key (Forest Temple)" : {
'keys.forest': None,
'total_keys.forest': None,
},
"Small Key (Fire Temple)" : {
'keys.fire': None,
'total_keys.fire': None,
},
"Small Key (Water Temple)" : {
'keys.water': None,
'total_keys.water': None,
},
"Small Key (Spirit Temple)" : {
'keys.spirit': None,
'total_keys.spirit': None,
},
"Small Key (Shadow Temple)" : {
'keys.shadow': None,
'total_keys.shadow': None,
},
"Small Key (Bottom of the Well)" : {
'keys.botw': None,
'total_keys.botw': None,
},
"Small Key (Gerudo Training Ground)" : {
'keys.gtg': None,
'total_keys.gtg': None,
},
"Small Key (Thieves Hideout)" : {
'keys.fortress': None,
'total_keys.fortress': None,
},
"Small Key (Ganons Castle)" : {
'keys.gc': None,
'total_keys.gc': None,
},
#HACK: these counts aren't used since exact counts based on whether the dungeon is MQ are defined above,
# but the entries need to be there for key rings to be valid starting items
"Small Key Ring (Forest Temple)" : {
'keys.forest': 6,
'total_keys.forest': 6,
},
"Small Key Ring (Fire Temple)" : {
'keys.fire': 8,
'total_keys.fire': 8,
},
"Small Key Ring (Water Temple)" : {
'keys.water': 6,
'total_keys.water': 6,
},
"Small Key Ring (Spirit Temple)" : {
'keys.spirit': 7,
'total_keys.spirit': 7,
},
"Small Key Ring (Shadow Temple)" : {
'keys.shadow': 6,
'total_keys.shadow': 6,
},
"Small Key Ring (Bottom of the Well)" : {
'keys.botw': 3,
'total_keys.botw': 3,
},
"Small Key Ring (Gerudo Training Ground)" : {
'keys.gtg': 9,
'total_keys.gtg': 9,
},
"Small Key Ring (Thieves Hideout)" : {
'keys.fortress': 4,
'total_keys.fortress': 4,
},
"Small Key Ring (Ganons Castle)" : {
'keys.gc': 3,
'total_keys.gc': 3,
},
}
giveable_items = set(chain(save_writes_table.keys(), bottle_types.keys(),
["Piece of Heart", "Piece of Heart (Treasure Chest Game)", "Heart Container", "Rupee (1)"]))
equipable_items = {
'equips_adult' : {
@ -977,7 +1181,6 @@ class SaveContext():
'bombchu',
'nayrus_love',
'beans',
'child_trade',
'bottle_1',
'bottle_2',
'bottle_3',

120
worlds/oot/SceneFlags.py Normal file
View File

@ -0,0 +1,120 @@
from math import ceil
from .LocationList import location_table
# Create a dict of dicts of the format:
# {
# scene_number_n : {
# room_setup_number: max_flags
# }
# }
# where room_setup_number defines the room + scene setup as ((setup << 6) + room) for scene n
# and max_flags is the highest used enemy flag for that setup/room
def get_collectible_flag_table(world):
scene_flags = {}
alt_list = []
for i in range(0, 101):
max_room_num = 0
max_enemy_flag = 0
scene_flags[i] = {}
for location in world.get_locations():
if(location.scene == i and location.type in ["Freestanding", "Pot", "FlyingPot", "Crate", "SmallCrate", "Beehive", "RupeeTower"]):
default = location.default
if(isinstance(default, list)): #List of alternative room/setup/flag to use
primary_tuple = default[0]
for c in range(1,len(default)):
alt_list.append((location, default[c], primary_tuple))
default = location.default[0] #Use the first tuple as the primary tuple
if(isinstance(default, tuple)):
room, setup, flag = default
room_setup = room + (setup << 6)
if(room_setup in scene_flags[i].keys()):
curr_room_max_flag = scene_flags[i][room_setup]
if flag > curr_room_max_flag:
scene_flags[i][room_setup] = flag
else:
scene_flags[i][room_setup] = flag
if len(scene_flags[i].keys()) == 0:
del scene_flags[i]
#scene_flags.append((i, max_enemy_flag))
return (scene_flags, alt_list)
# Create a byte array from the scene flag table created by get_collectible_flag_table
def get_collectible_flag_table_bytes(scene_flag_table):
num_flag_bytes = 0
bytes = bytearray()
bytes.append(len(scene_flag_table.keys()))
for scene_id in scene_flag_table.keys():
rooms = scene_flag_table[scene_id]
room_count = len(rooms.keys())
bytes.append(scene_id)
bytes.append(room_count)
for room in rooms:
bytes.append(room)
bytes.append((num_flag_bytes & 0xFF00) >> 8)
bytes.append(num_flag_bytes & 0x00FF )
num_flag_bytes += ceil((rooms[room] + 1) / 8)
return bytes, num_flag_bytes
def get_alt_list_bytes(alt_list):
bytes = bytearray()
for entry in alt_list:
location, alt, primary = entry
room, scene_setup, flag = alt
alt_override = (room << 8) + (scene_setup << 14) + flag
room, scene_setup, flag = primary
primary_override = (room << 8) + (scene_setup << 14) + flag
bytes.append(location.scene)
bytes.append(0x06)
bytes.append((alt_override & 0xFF00) >> 8)
bytes.append(alt_override & 0xFF)
bytes.append(location.scene)
bytes.append(0x06)
bytes.append((primary_override & 0xFF00) >> 8)
bytes.append(primary_override & 0xFF)
return bytes
# AP method to retrieve address + bit for each item
# Based on get_collectible_flag_offset in the C code
def get_collectible_flag_addresses(world, collectible_scene_flags_table):
# Ported directly from get_items.c
def get_collectible_flag_offset(scene: int, room: int, setup_id: int) -> int:
num_scenes = collectible_scene_flags_table[0]
index = 1
scene_id = 0
room_id = 0
room_setup_count = 0
room_byte_offset = 0
# Loop through collectible_scene_flags_table until we find the right scene
while num_scenes > 0:
scene_id = collectible_scene_flags_table[index]
room_setup_count = collectible_scene_flags_table[index+1]
index += 2
if scene_id == scene: # found the scene
# Loop through each room/setup combination until we find the right one.
for i in range(room_setup_count):
room_id = collectible_scene_flags_table[index] & 0x3F
setup_id_temp = (collectible_scene_flags_table[index] & 0xC0) >> 6
room_byte_offset = (collectible_scene_flags_table[index+1] << 8) + collectible_scene_flags_table[index+2]
index += 3
if room_id == room and setup_id_temp == setup_id:
return room_byte_offset
else: # Not the right scene, skip to the next one
index += 3 * room_setup_count
num_scenes -= 1
return -1
collectible_flag_addresses = {}
for location in world.get_locations():
if location.type in ["Freestanding", "Pot", "FlyingPot", "Crate", "SmallCrate", "Beehive", "RupeeTower"]:
default = location.default
if isinstance(default, list):
default = default[0]
room, setup, flag = default
offset = get_collectible_flag_offset(location.scene, room, setup)
item_id = location.address
collectible_flag_addresses[item_id] = [offset, flag]
return collectible_flag_addresses

View File

@ -4,7 +4,7 @@ import subprocess
import Utils
from functools import lru_cache
__version__ = '6.1.0 f.LUM'
__version__ = '7.1.0'
def data_path(*args):
@ -97,3 +97,9 @@ def compare_version(a, b):
if sa[i] < sb[i]:
return -1
return 0
# https://stackoverflow.com/a/23146126
def find_last(source_list, sought_element):
for reverse_index, element in enumerate(reversed(source_list)):
if element == sought_element:
return len(source_list) - 1 - reverse_index

View File

@ -1,7 +1,8 @@
import logging
import threading
import copy
from typing import Optional, List, AbstractSet # remove when 3.8 support is dropped
import functools
from typing import Optional, List, AbstractSet, Union # remove when 3.8 support is dropped
from collections import Counter, deque
from string import printable
@ -10,8 +11,9 @@ logger = logging.getLogger("Ocarina of Time")
from .Location import OOTLocation, LocationFactory, location_name_to_id
from .Entrance import OOTEntrance
from .EntranceShuffle import shuffle_random_entrances, entrance_shuffle_table, EntranceShuffleError
from .Hints import HintArea
from .Items import OOTItem, item_table, oot_data_to_ap_id, oot_is_item_of_type
from .ItemPool import generate_itempool, add_dungeon_items, get_junk_item, get_junk_pool
from .ItemPool import generate_itempool, get_junk_item, get_junk_pool
from .Regions import OOTRegion, TimeOfDay
from .Rules import set_rules, set_shop_rules, set_entrances_based_rules
from .RuleParser import Rule_AST_Transformer
@ -21,22 +23,19 @@ from .LocationList import business_scrubs, set_drop_location_names, dungeon_song
from .DungeonList import dungeon_table, create_dungeons
from .LogicTricks import normalized_name_tricks
from .Rom import Rom
from .Patches import patch_rom
from .Patches import OoTContainer, patch_rom
from .N64Patch import create_patch_file
from .Cosmetics import patch_cosmetics
from .Hints import hint_dist_keys, get_hint_area, buildWorldGossipHints
from .HintList import getRequiredHints
from .SaveContext import SaveContext
from Utils import get_options, output_path
from Utils import get_options
from BaseClasses import MultiWorld, CollectionState, RegionType, Tutorial, LocationProgressType
from Options import Range, Toggle, OptionList
from Options import Range, Toggle, VerifyKeys
from Fill import fill_restrictive, fast_fill, FillError
from worlds.generic.Rules import exclusion_rules, add_item_rule
from ..AutoWorld import World, AutoLogicRegister, WebWorld
location_id_offset = 67000
# OoT's generate_output doesn't benefit from more than 2 threads, instead it uses a lot of memory.
i_o_limiter = threading.Semaphore(2)
@ -100,13 +99,18 @@ class OOTWorld(World):
option_definitions: dict = oot_options
topology_present: bool = True
item_name_to_id = {item_name: oot_data_to_ap_id(data, False) for item_name, data in item_table.items() if
data[2] is not None}
data[2] is not None and item_name not in {
'Keaton Mask', 'Skull Mask', 'Spooky Mask', 'Bunny Hood',
'Mask of Truth', 'Goron Mask', 'Zora Mask', 'Gerudo Mask',
'Buy Magic Bean', 'Milk',
'Small Key', 'Map', 'Compass', 'Boss Key',
}} # These are items which aren't used, but have get-item values
location_name_to_id = location_name_to_id
web = OOTWeb()
data_version = 2
data_version = 3
required_client_version = (0, 3, 2)
required_client_version = (0, 3, 6)
item_name_groups = {
# internal groups
@ -133,6 +137,7 @@ class OOTWorld(World):
def __init__(self, world, player):
self.hint_data_available = threading.Event()
self.collectible_flags_available = threading.Event()
super(OOTWorld, self).__init__(world, player)
@classmethod
@ -148,7 +153,7 @@ class OOTWorld(World):
option_value = int(result)
elif isinstance(result, Toggle):
option_value = bool(result)
elif isinstance(result, OptionList):
elif isinstance(result, VerifyKeys):
option_value = result.value
else:
option_value = result.current_key
@ -161,6 +166,7 @@ class OOTWorld(World):
self.songs_as_items = False
self.file_hash = [self.multiworld.random.randint(0, 31) for i in range(5)]
self.connect_name = ''.join(self.multiworld.random.choices(printable, k=16))
self.collectible_flag_addresses = {}
# Incompatible option handling
# ER and glitched logic are not compatible; glitched takes priority
@ -171,7 +177,15 @@ class OOTWorld(World):
self.shuffle_overworld_entrances = False
self.owl_drops = False
self.warp_songs = False
self.spawn_positions = False
self.spawn_positions = 'off'
# Fix spawn positions option
new_sp = []
if self.spawn_positions in {'child', 'both'}:
new_sp.append('child')
if self.spawn_positions in {'adult', 'both'}:
new_sp.append('adult')
self.spawn_positions = new_sp
# Closed forest and adult start are not compatible; closed forest takes priority
if self.open_forest == 'closed':
@ -180,13 +194,9 @@ class OOTWorld(World):
if (self.shuffle_interior_entrances == 'all' or self.shuffle_overworld_entrances or self.warp_songs or self.spawn_positions):
self.open_forest = 'closed_deku'
# Skip child zelda and shuffle egg are not compatible; skip-zelda takes priority
if self.skip_child_zelda:
self.shuffle_weird_egg = False
# Ganon boss key should not be in itempool in triforce hunt
if self.triforce_hunt:
self.shuffle_ganon_bosskey = 'remove'
self.shuffle_ganon_bosskey = 'triforce'
# If songs/keys locked to own world by settings, add them to local_items
local_types = []
@ -196,7 +206,7 @@ class OOTWorld(World):
local_types += ['Map', 'Compass']
if self.shuffle_smallkeys != 'keysanity':
local_types.append('SmallKey')
if self.shuffle_fortresskeys != 'keysanity':
if self.shuffle_hideoutkeys != 'keysanity':
local_types.append('HideoutSmallKey')
if self.shuffle_bosskeys != 'keysanity':
local_types.append('BossKey')
@ -219,15 +229,6 @@ class OOTWorld(World):
chosen_trials = self.multiworld.random.sample(trial_list, self.trials) # chooses a list of trials to NOT skip
self.skipped_trials = {trial: (trial not in chosen_trials) for trial in trial_list}
# Determine which dungeons are MQ
# Possible future plan: allow user to pick which dungeons are MQ
if self.logic_rules == 'glitchless':
mq_dungeons = self.multiworld.random.sample(dungeon_table, self.mq_dungeons)
else:
self.mq_dungeons = 0
mq_dungeons = []
self.dungeon_mq = {item['name']: (item in mq_dungeons) for item in dungeon_table}
# Determine tricks in logic
if self.logic_rules == 'glitchless':
for trick in self.logic_tricks:
@ -245,15 +246,31 @@ class OOTWorld(World):
setattr(self, trick['name'], True)
# Not implemented for now, but needed to placate the generator. Remove as they are implemented
self.mq_dungeons_random = False # this will be a deprecated option later
self.ocarina_songs = False # just need to pull in the OcarinaSongs module
self.mix_entrance_pools = False
self.decouple_entrances = False
self.available_tokens = 100
# Deprecated LACS options
self.lacs_condition = 'vanilla'
self.lacs_stones = 3
self.lacs_medallions = 6
self.lacs_rewards = 9
self.lacs_tokens = 100
self.lacs_hearts = 20
# RuleParser hack
self.triforce_goal_per_world = self.triforce_goal
# Set internal names used by the OoT generator
self.keysanity = self.shuffle_smallkeys in ['keysanity', 'remove', 'any_dungeon', 'overworld']
self.trials_random = self.multiworld.trials[self.player].randomized
self.mq_dungeons_random = self.multiworld.mq_dungeons[self.player].randomized
self.mq_dungeons_random = self.multiworld.mq_dungeons_count[self.player].randomized
self.easier_fire_arrow_entry = self.fae_torch_count < 24
if self.misc_hints:
self.misc_hints = ['ganondorf', 'altar', 'warp_songs', 'dampe_diary',
'10_skulltulas', '20_skulltulas', '30_skulltulas', '40_skulltulas', '50_skulltulas']
else:
self.misc_hints = []
# Hint stuff
self.clearer_hints = True # this is being enforced since non-oot items do not have non-clear hint text
@ -261,8 +278,11 @@ class OOTWorld(World):
self.required_locations = []
self.empty_areas = {}
self.major_item_locations = []
self.hinted_dungeon_reward_locations = {}
# ER names
self.shuffle_special_dungeon_entrances = self.shuffle_dungeon_entrances == 'all'
self.shuffle_dungeon_entrances = self.shuffle_dungeon_entrances != 'off'
self.ensure_tod_access = (self.shuffle_interior_entrances != 'off') or self.shuffle_overworld_entrances or self.spawn_positions
self.entrance_shuffle = (self.shuffle_interior_entrances != 'off') or self.shuffle_grotto_entrances or self.shuffle_dungeon_entrances or \
self.shuffle_overworld_entrances or self.owl_drops or self.warp_songs or self.spawn_positions
@ -275,6 +295,60 @@ class OOTWorld(World):
elif self.shopsanity == 'fixed_number':
self.shopsanity = str(self.shop_slots)
# Rename options
self.dungeon_shortcuts_choice = self.dungeon_shortcuts
if self.dungeon_shortcuts_choice == 'random_dungeons':
self.dungeon_shortcuts_choice = 'random'
self.key_rings_list = {s.replace("'", "") for s in self.key_rings_list}
self.dungeon_shortcuts = {s.replace("'", "") for s in self.dungeon_shortcuts_list}
self.mq_dungeons_specific = {s.replace("'", "") for s in self.mq_dungeons_list}
# self.empty_dungeons_specific = {s.replace("'", "") for s in self.empty_dungeons_list}
# Determine which dungeons have key rings.
keyring_dungeons = [d['name'] for d in dungeon_table if d['small_key']] + ['Thieves Hideout']
if self.key_rings == 'off':
self.key_rings = []
elif self.key_rings == 'all':
self.key_rings = keyring_dungeons
elif self.key_rings == 'choose':
self.key_rings = self.key_rings_list
elif self.key_rings == 'random_dungeons':
self.key_rings = self.multiworld.random.sample(keyring_dungeons,
self.multiworld.random.randint(0, len(keyring_dungeons)))
# Determine which dungeons are MQ. Not compatible with glitched logic.
mq_dungeons = set()
if self.logic_rules != 'glitched':
if self.mq_dungeons_mode == 'mq':
mq_dungeons = dungeon_table.keys()
elif self.mq_dungeons_mode == 'specific':
mq_dungeons = self.mq_dungeons_specific
elif self.mq_dungeons_mode == 'count':
mq_dungeons = self.multiworld.random.sample(dungeon_table, self.mq_dungeons_count)
else:
self.mq_dungeons_mode = 'count'
self.mq_dungeons_count = 0
self.dungeon_mq = {item['name']: (item['name'] in mq_dungeons) for item in dungeon_table}
# Empty dungeon placeholder for the moment
self.empty_dungeons = {name: False for name in self.dungeon_mq}
# Determine which dungeons have shortcuts. Not compatible with glitched logic.
shortcut_dungeons = ['Deku Tree', 'Dodongos Cavern', \
'Jabu Jabus Belly', 'Forest Temple', 'Fire Temple', \
'Water Temple', 'Shadow Temple', 'Spirit Temple']
if self.logic_rules != 'glitched':
if self.dungeon_shortcuts_choice == 'off':
self.dungeon_shortcuts = set()
elif self.dungeon_shortcuts_choice == 'all':
self.dungeon_shortcuts = set(shortcut_dungeons)
elif self.dungeon_shortcuts_choice == 'random':
self.dungeon_shortcuts = self.multiworld.random.sample(shortcut_dungeons,
self.multiworld.random.randint(0, len(shortcut_dungeons)))
# == 'choice', leave as previous
else:
self.dungeon_shortcuts = set()
# fixing some options
# Fixes starting time spelling: "witching_hour" -> "witching-hour"
self.starting_tod = self.starting_tod.replace('_', '-')
@ -286,7 +360,7 @@ class OOTWorld(World):
self.added_hint_types = {}
self.item_added_hint_types = {}
self.hint_exclusions = set()
if self.skip_child_zelda:
if self.shuffle_child_trade == 'skip_child_zelda':
self.hint_exclusions.add('Song from Impa')
self.hint_type_overrides = {}
self.item_hint_type_overrides = {}
@ -317,7 +391,7 @@ class OOTWorld(World):
self.always_hints = [hint.name for hint in getRequiredHints(self)]
# Determine items which are not considered advancement based on settings. They will never be excluded.
self.nonadvancement_items = {'Double Defense', 'Ice Arrows'}
self.nonadvancement_items = {'Double Defense'}
if (self.damage_multiplier != 'ohko' and self.damage_multiplier != 'quadruple' and
self.shuffle_scrubs == 'off' and not self.shuffle_grotto_entrances):
# nayru's love may be required to prevent forced damage
@ -330,6 +404,22 @@ class OOTWorld(World):
# Serenade and Prelude are never required unless one of those settings is enabled
self.nonadvancement_items.add('Serenade of Water')
self.nonadvancement_items.add('Prelude of Light')
if not self.blue_fire_arrows:
# Ice Arrows serve no purpose if they're not hacked to have one
self.nonadvancement_items.add('Ice Arrows')
if not self.bombchus_in_logic:
# Nonrenewable bombchus are not a default logical explosive
self.nonadvancement_items.update({
'Bombchus (5)',
'Bombchus (10)',
'Bombchus (20)',
})
if not (self.bridge == 'hearts' or self.shuffle_ganon_bosskey == 'hearts'):
self.nonadvancement_items.update({
'Heart Container',
'Piece of Heart',
'Piece of Heart (Treasure Chest Game)'
})
if self.logic_rules == 'glitchless':
# Both two-handed swords can be required in glitch logic, so only consider them nonprogression in glitchless
self.nonadvancement_items.add('Biggoron Sword')
@ -350,10 +440,14 @@ class OOTWorld(World):
new_region.font_color = region['font_color']
if 'scene' in region:
new_region.scene = region['scene']
if 'hint' in region:
new_region.hint_text = region['hint']
if 'dungeon' in region:
new_region.dungeon = region['dungeon']
if 'is_boss_room' in region:
new_region.is_boss_room = region['is_boss_room']
if 'hint' in region:
new_region.set_hint_data(region['hint'])
if 'alt_hint' in region:
new_region.alt_hint = HintArea[region['alt_hint']]
if 'time_passes' in region:
new_region.time_passes = region['time_passes']
new_region.provides_time = TimeOfDay.ALL
@ -404,7 +498,7 @@ class OOTWorld(World):
def set_scrub_prices(self):
# Get Deku Scrub Locations
scrub_locations = [location for location in self.get_locations() if 'Deku Scrub' in location.name]
scrub_locations = [location for location in self.get_locations() if location.type in {'Scrub', 'GrottoScrub'}]
scrub_dictionary = {}
self.scrub_prices = {}
for location in scrub_locations:
@ -442,7 +536,18 @@ class OOTWorld(World):
for location in region.locations:
if location.type == 'Shop':
if location.name[-1:] in shop_item_indexes[:shop_item_count]:
if self.shopsanity_prices == 'normal':
self.shop_prices[location.name] = int(self.multiworld.random.betavariate(1.5, 2) * 60) * 5
elif self.shopsanity_prices == 'affordable':
self.shop_prices[location.name] = 10
elif self.shopsanity_prices == 'starting_wallet':
self.shop_prices[location.name] = self.multiworld.random.randrange(0,100,5)
elif self.shopsanity_prices == 'adults_wallet':
self.shop_prices[location.name] = self.multiworld.random.randrange(0,201,5)
elif self.shopsanity_prices == 'giants_wallet':
self.shop_prices[location.name] = self.multiworld.random.randrange(0,501,5)
elif self.shopsanity_prices == 'tycoons_wallet':
self.shop_prices[location.name] = self.multiworld.random.randrange(0,1000,5)
def fill_bosses(self, bossCount=9):
boss_location_names = (
@ -471,6 +576,7 @@ class OOTWorld(World):
loc = prize_locs.pop()
loc.place_locked_item(item)
self.multiworld.itempool.remove(item)
self.hinted_dungeon_reward_locations[item.name] = loc
def create_item(self, name: str):
if name in item_table:
@ -495,11 +601,13 @@ class OOTWorld(World):
else:
world_type = 'Glitched World'
overworld_data_path = data_path(world_type, 'Overworld.json')
bosses_data_path = data_path(world_type, 'Bosses.json')
menu = OOTRegion('Menu', None, None, self.player)
start = OOTEntrance(self.player, self.multiworld, 'New Game', menu)
menu.exits.append(start)
self.multiworld.regions.append(menu)
self.load_regions_from_json(overworld_data_path)
self.load_regions_from_json(bosses_data_path)
start.connect(self.multiworld.get_region('Root', self.player))
create_dungeons(self)
self.parser.create_delayed_rules()
@ -514,9 +622,10 @@ class OOTWorld(World):
exit.connect(self.multiworld.get_region(exit.vanilla_connected_region, self.player))
def create_items(self):
# Uniquely rename drop locations for each region and erase them from the spoiler
set_drop_location_names(self)
# Generate itempool
generate_itempool(self)
add_dungeon_items(self)
# Add dungeon rewards
rewardlist = sorted(list(self.item_name_groups['rewards']))
self.itempool += map(self.create_item, rewardlist)
@ -528,9 +637,6 @@ class OOTWorld(World):
if item.name in self.remove_from_start_inventory:
self.remove_from_start_inventory.remove(item.name)
removed_items.append(item.name)
else:
if item.name not in SaveContext.giveable_items:
raise Exception(f"Invalid OoT starting item: {item.name}")
else:
self.starting_items[item.name] += 1
if item.type == 'Song':
@ -548,6 +654,9 @@ class OOTWorld(World):
self.multiworld.itempool += self.itempool
self.remove_from_start_inventory.extend(removed_items)
# Fill boss prizes. needs to happen before entrance shuffle
self.fill_bosses()
def set_rules(self):
# This has to run AFTER creating items but BEFORE set_entrances_based_rules
if self.entrance_shuffle:
@ -587,12 +696,6 @@ class OOTWorld(World):
def generate_basic(self): # mostly killing locations that shouldn't exist by settings
# Fill boss prizes. needs to happen before killing unreachable locations
self.fill_bosses()
# Uniquely rename drop locations for each region and erase them from the spoiler
set_drop_location_names(self)
# Gather items for ice trap appearances
self.fake_items = []
if self.ice_trap_appearance in ['major_only', 'anything']:
@ -628,72 +731,32 @@ class OOTWorld(World):
def pre_fill(self):
def get_names(items):
for item in items:
yield item.name
# Place/set rules for dungeon items
itempools = {
'dungeon': set(),
'overworld': set(),
'any_dungeon': set(),
}
any_dungeon_locations = []
for dungeon in self.dungeons:
itempools['dungeon'] = set()
# Put the dungeon items into their appropriate pools.
# Build in reverse order since we need to fill boss key first and pop() returns the last element
if self.shuffle_mapcompass in itempools:
itempools[self.shuffle_mapcompass].update(get_names(dungeon.dungeon_items))
if self.shuffle_smallkeys in itempools:
itempools[self.shuffle_smallkeys].update(get_names(dungeon.small_keys))
shufflebk = self.shuffle_bosskeys if dungeon.name != 'Ganons Castle' else self.shuffle_ganon_bosskey
if shufflebk in itempools:
itempools[shufflebk].update(get_names(dungeon.boss_key))
# We can't put a dungeon item on the end of a dungeon if a song is supposed to go there. Make sure not to include it.
dungeon_locations = [loc for region in dungeon.regions for loc in region.locations
if loc.item is None and (
self.shuffle_song_items != 'dungeon' or loc.name not in dungeon_song_locations)]
if itempools['dungeon']: # only do this if there's anything to shuffle
dungeon_itempool = [item for item in self.multiworld.itempool if item.player == self.player and item.name in itempools['dungeon']]
for item in dungeon_itempool:
# Place dungeon items
special_fill_types = ['GanonBossKey', 'BossKey', 'SmallKey', 'HideoutSmallKey', 'Map', 'Compass']
world_items = [item for item in self.multiworld.itempool if item.player == self.player]
for fill_stage in special_fill_types:
stage_items = list(filter(lambda item: oot_is_item_of_type(item, fill_stage), world_items))
if not stage_items:
continue
if fill_stage in ['GanonBossKey', 'HideoutSmallKey']:
locations = gather_locations(self.multiworld, fill_stage, self.player)
if isinstance(locations, list):
for item in stage_items:
self.multiworld.itempool.remove(item)
self.multiworld.random.shuffle(dungeon_locations)
fill_restrictive(self.multiworld, self.multiworld.get_all_state(False), dungeon_locations,
dungeon_itempool, True, True)
any_dungeon_locations.extend(dungeon_locations) # adds only the unfilled locations
# Now fill items that can go into any dungeon. Retrieve the Gerudo Fortress keys from the pool if necessary
if self.shuffle_fortresskeys == 'any_dungeon':
itempools['any_dungeon'].add('Small Key (Thieves Hideout)')
if itempools['any_dungeon']:
any_dungeon_itempool = [item for item in self.multiworld.itempool if item.player == self.player and item.name in itempools['any_dungeon']]
for item in any_dungeon_itempool:
self.multiworld.random.shuffle(locations)
fill_restrictive(self.multiworld, self.multiworld.get_all_state(False), locations, stage_items,
single_player_placement=True, lock=True)
else:
for dungeon_info in dungeon_table:
dungeon_name = dungeon_info['name']
locations = gather_locations(self.multiworld, fill_stage, self.player, dungeon=dungeon_name)
if isinstance(locations, list):
dungeon_items = list(filter(lambda item: dungeon_name in item.name, stage_items))
for item in dungeon_items:
self.multiworld.itempool.remove(item)
any_dungeon_itempool.sort(key=lambda item:
{'GanonBossKey': 4, 'BossKey': 3, 'SmallKey': 2, 'HideoutSmallKey': 1}.get(item.type, 0))
self.multiworld.random.shuffle(any_dungeon_locations)
fill_restrictive(self.multiworld, self.multiworld.get_all_state(False), any_dungeon_locations,
any_dungeon_itempool, True, True)
# If anything is overworld-only, fill into local non-dungeon locations
if self.shuffle_fortresskeys == 'overworld':
itempools['overworld'].add('Small Key (Thieves Hideout)')
if itempools['overworld']:
overworld_itempool = [item for item in self.multiworld.itempool if item.player == self.player and item.name in itempools['overworld']]
for item in overworld_itempool:
self.multiworld.itempool.remove(item)
overworld_itempool.sort(key=lambda item:
{'GanonBossKey': 4, 'BossKey': 3, 'SmallKey': 2, 'HideoutSmallKey': 1}.get(item.type, 0))
non_dungeon_locations = [loc for loc in self.get_locations() if
not loc.item and loc not in any_dungeon_locations and
(loc.type != 'Shop' or loc.name in self.shop_prices) and
(loc.type != 'Song' or self.shuffle_song_items != 'song') and
(loc.name not in dungeon_song_locations or self.shuffle_song_items != 'dungeon')]
self.multiworld.random.shuffle(non_dungeon_locations)
fill_restrictive(self.multiworld, self.multiworld.get_all_state(False), non_dungeon_locations,
overworld_itempool, True, True)
self.multiworld.random.shuffle(locations)
fill_restrictive(self.multiworld, self.multiworld.get_all_state(False), locations, dungeon_items,
single_player_placement=True, lock=True)
# Place songs
# 5 built-in retries because this section can fail sometimes
@ -778,10 +841,10 @@ class OOTWorld(World):
# If skip child zelda is active and Song from Impa is unfilled, put a local giveable item into it.
impa = self.multiworld.get_location("Song from Impa", self.player)
if self.skip_child_zelda:
if self.shuffle_child_trade == 'skip_child_zelda':
if impa.item is None:
item_to_place = self.multiworld.random.choice(list(item for item in self.multiworld.itempool if
item.player == self.player and item.name in SaveContext.giveable_items))
item_to_place = self.multiworld.random.choice(
list(item for item in self.multiworld.itempool if item.player == self.player))
impa.place_locked_item(item_to_place)
self.multiworld.itempool.remove(item_to_place)
# Give items to startinventory
@ -801,11 +864,14 @@ class OOTWorld(World):
ganon_junk_fill = 2 / 9
elif self.bridge == 'tokens':
ganon_junk_fill = self.bridge_tokens / 100
elif self.bridge == 'hearts':
ganon_junk_fill = self.bridge_hearts / 20
elif self.bridge == 'open':
ganon_junk_fill = 0
else:
raise Exception("Unexpected bridge setting")
ganon_junk_fill = min(1, ganon_junk_fill)
gc = next(filter(lambda dungeon: dungeon.name == 'Ganons Castle', self.dungeons))
locations = [loc.name for region in gc.regions for loc in region.locations if loc.item is None]
junk_fill_locations = self.multiworld.random.sample(locations, round(len(locations) * ganon_junk_fill))
@ -816,48 +882,12 @@ class OOTWorld(World):
for loc in self.get_locations():
if loc.address is not None and (
not loc.show_in_spoiler or oot_is_item_of_type(loc.item, 'Shop')
or (self.skip_child_zelda and loc.name in ['HC Zeldas Letter', 'Song from Impa'])):
or (self.shuffle_child_trade == 'skip_child_zelda' and loc.name in ['HC Zeldas Letter', 'Song from Impa'])):
loc.address = None
# Handle item-linked dungeon items and songs
@classmethod
def stage_pre_fill(cls, multiworld: MultiWorld):
def gather_locations(item_type: str, players: AbstractSet[int], dungeon: str = '') -> Optional[List[OOTLocation]]:
type_to_setting = {
'Song': 'shuffle_song_items',
'Map': 'shuffle_mapcompass',
'Compass': 'shuffle_mapcompass',
'SmallKey': 'shuffle_smallkeys',
'BossKey': 'shuffle_bosskeys',
'HideoutSmallKey': 'shuffle_fortresskeys',
'GanonBossKey': 'shuffle_ganon_bosskey',
}
fill_opts = {p: getattr(multiworld.worlds[p], type_to_setting[item_type]) for p in players}
locations = []
if item_type == 'Song':
if any(map(lambda v: v == 'any', fill_opts.values())):
return None
for player, option in fill_opts.items():
if option == 'song':
condition = lambda location: location.type == 'Song'
elif option == 'dungeon':
condition = lambda location: location.name in dungeon_song_locations
locations += filter(condition, multiworld.get_unfilled_locations(player=player))
else:
if any(map(lambda v: v == 'keysanity', fill_opts.values())):
return None
for player, option in fill_opts.items():
if option == 'dungeon':
condition = lambda location: getattr(location.parent_region.dungeon, 'name', None) == dungeon
elif option == 'overworld':
condition = lambda location: location.parent_region.dungeon is None
elif option == 'any_dungeon':
condition = lambda location: location.parent_region.dungeon is not None
locations += filter(condition, multiworld.get_unfilled_locations(player=player))
return locations
special_fill_types = ['Song', 'GanonBossKey', 'BossKey', 'SmallKey', 'HideoutSmallKey', 'Map', 'Compass']
for group_id, group in multiworld.groups.items():
if group['game'] != cls.game:
@ -869,7 +899,7 @@ class OOTWorld(World):
continue
if fill_stage in ['Song', 'GanonBossKey', 'HideoutSmallKey']:
# No need to subdivide by dungeon name
locations = gather_locations(fill_stage, group['players'])
locations = gather_locations(multiworld, fill_stage, group['players'])
if isinstance(locations, list):
for item in group_stage_items:
multiworld.itempool.remove(item)
@ -889,7 +919,7 @@ class OOTWorld(World):
# Perform the fill task once per dungeon
for dungeon_info in dungeon_table:
dungeon_name = dungeon_info['name']
locations = gather_locations(fill_stage, group['players'], dungeon=dungeon_name)
locations = gather_locations(multiworld, fill_stage, group['players'], dungeon=dungeon_name)
if isinstance(locations, list):
group_dungeon_items = list(filter(lambda item: dungeon_name in item.name, group_stage_items))
for item in group_dungeon_items:
@ -916,12 +946,20 @@ class OOTWorld(World):
rom = Rom(file=get_options()['oot_options']['rom_file'])
if self.hints != 'none':
buildWorldGossipHints(self)
# try:
patch_rom(self, rom)
# except Exception as e:
# print(e)
patch_cosmetics(self, rom)
rom.update_header()
create_patch_file(rom, output_path(output_directory, outfile_name + '.apz5'))
patch_data = create_patch_file(rom)
rom.restore()
apz5 = OoTContainer(patch_data, outfile_name, output_directory,
player=self.player,
player_name=self.multiworld.get_player_name(self.player))
apz5.write()
# Write entrances to spoiler log
all_entrances = self.get_shuffled_entrances()
all_entrances.sort(reverse=True, key=lambda x: x.name)
@ -966,7 +1004,7 @@ class OOTWorld(World):
items_by_region[player][r.hint_text] = {'dungeon': False, 'weight': 0, 'is_barren': True}
for d in multiworld.worlds[player].dungeons:
items_by_region[player][d.hint_text] = {'dungeon': True, 'weight': 0, 'is_barren': True}
del (items_by_region[player]["Link's Pocket"])
del (items_by_region[player]["Link's pocket"])
del (items_by_region[player][None])
if item_hint_players: # loop once over all locations to gather major items. Check oot locations for barren/woth if needed
@ -980,7 +1018,7 @@ class OOTWorld(World):
if loc.game == "Ocarina of Time" and loc.item.code and (not loc.locked or
(oot_is_item_of_type(loc.item, 'Song') or
(oot_is_item_of_type(loc.item, 'SmallKey') and multiworld.worlds[loc.player].shuffle_smallkeys == 'any_dungeon') or
(oot_is_item_of_type(loc.item, 'HideoutSmallKey') and multiworld.worlds[loc.player].shuffle_fortresskeys == 'any_dungeon') or
(oot_is_item_of_type(loc.item, 'HideoutSmallKey') and multiworld.worlds[loc.player].shuffle_hideoutkeys == 'any_dungeon') or
(oot_is_item_of_type(loc.item, 'BossKey') and multiworld.worlds[loc.player].shuffle_bosskeys == 'any_dungeon') or
(oot_is_item_of_type(loc.item, 'GanonBossKey') and multiworld.worlds[loc.player].shuffle_ganon_bosskey == 'any_dungeon'))):
if loc.player in barren_hint_players:
@ -1017,22 +1055,42 @@ class OOTWorld(World):
for autoworld in multiworld.get_game_worlds("Ocarina of Time"):
autoworld.hint_data_available.set()
def fill_slot_data(self):
self.collectible_flags_available.wait()
return {
'collectible_override_flags': self.collectible_override_flags,
'collectible_flag_offsets': self.collectible_flag_offsets
}
def modify_multidata(self, multidata: dict):
# Replace connect name
multidata['connect_names'][self.connect_name] = multidata['connect_names'][self.multiworld.player_name[self.player]]
# Remove undesired items from start_inventory
# This is because we don't want them to show up in the autotracker,
# they just don't exist in-game.
for item_name in self.remove_from_start_inventory:
item_id = self.item_name_to_id.get(item_name, None)
if item_id is None:
continue
multidata["precollected_items"][self.player].remove(item_id)
def extend_hint_information(self, er_hint_data: dict):
er_hint_data[self.player] = {}
hint_entrances = set()
for entrance in entrance_shuffle_table:
if entrance[0] in {'Dungeon', 'DungeonSpecial', 'Interior', 'SpecialInterior', 'Grotto', 'Grave'}:
hint_entrances.add(entrance[1][0])
if len(entrance) > 2:
hint_entrances.add(entrance[2][0])
# Get main hint entrance to region.
# If the region is directly adjacent to a hint-entrance, we return that one.
# If it's in a dungeon, scan all the entrances for all the regions in the dungeon.
# This should terminate on the first region anyway, but we scan everything to be safe.
# If it's one of the special cases, go one level deeper.
# If it's a boss room, go one level deeper to the boss door region, which is in a dungeon.
# Otherwise return None.
def get_entrance_to_region(region):
special_case_regions = {
@ -1048,33 +1106,50 @@ class OOTWorld(World):
for e in r.entrances:
if e.name in hint_entrances:
return e
if region.name in special_case_regions:
if region.is_boss_room or region.name in special_case_regions:
return get_entrance_to_region(region.entrances[0].parent_region)
return None
# Remove undesired items from start_inventory
# This is because we don't want them to show up in the autotracker,
# they just don't exist in-game.
for item_name in self.remove_from_start_inventory:
item_id = self.item_name_to_id.get(item_name, None)
if item_id is None:
continue
multidata["precollected_items"][self.player].remove(item_id)
# Add ER hint data
if self.shuffle_interior_entrances != 'off' or self.shuffle_dungeon_entrances or self.shuffle_grotto_entrances:
er_hint_data = {}
if (self.shuffle_interior_entrances != 'off' or self.shuffle_dungeon_entrances
or self.shuffle_grotto_entrances or self.shuffle_bosses != 'off'):
for region in self.regions:
if not any(bool(loc.address) for loc in region.locations): # check if region has any non-event locations
continue
main_entrance = get_entrance_to_region(region)
if main_entrance is not None and main_entrance.shuffled:
if main_entrance is not None and (main_entrance.shuffled or (region.is_boss_room and self.shuffle_bosses != 'off')):
for location in region.locations:
if type(location.address) == int:
er_hint_data[location.address] = main_entrance.name
multidata['er_hint_data'][self.player] = er_hint_data
er_hint_data[self.player][location.address] = main_entrance.name
logger.debug(f"Set {location.name} hint data to {main_entrance.name}")
# Key ring handling:
# Key rings are multiple items glued together into one, so we need to give
# the appropriate number of keys in the collection state when they are
# picked up.
def collect(self, state: CollectionState, item: OOTItem) -> bool:
if item.advancement and item.special and item.special.get('alias', False):
alt_item_name, count = item.special.get('alias')
state.prog_items[alt_item_name, self.player] += count
return True
return super().collect(state, item)
def remove(self, state: CollectionState, item: OOTItem) -> bool:
if item.advancement and item.special and item.special.get('alias', False):
alt_item_name, count = item.special.get('alias')
state.prog_items[alt_item_name, self.player] -= count
if state.prog_items[alt_item_name, self.player] < 1:
del (state.prog_items[alt_item_name, self.player])
return True
return super().remove(state, item)
# Helper functions
def region_has_shortcuts(self, regionname):
region = self.get_region(regionname)
if not region.dungeon:
region = region.entrances[0].parent_region
return region.dungeon.name in self.dungeon_shortcuts
def get_shufflable_entrances(self, type=None, only_primary=False):
return [entrance for entrance in self.multiworld.get_entrances() if (entrance.player == self.player and
(type == None or entrance.type == type) and
@ -1115,7 +1190,7 @@ class OOTWorld(World):
return False
if item.type == 'SmallKey' and self.shuffle_smallkeys in ['dungeon', 'vanilla']:
return False
if item.type == 'HideoutSmallKey' and self.shuffle_fortresskeys == 'vanilla':
if item.type == 'HideoutSmallKey' and self.shuffle_hideoutkeys == 'vanilla':
return False
if item.type == 'BossKey' and self.shuffle_bosskeys in ['dungeon', 'vanilla']:
return False
@ -1130,7 +1205,7 @@ class OOTWorld(World):
all_state = self.multiworld.get_all_state(use_cache=False)
# Remove event progression items
for item, player in all_state.prog_items:
if player == self.player and (item not in item_table or (item_table[item][2] is None and item_table[item][0] != 'DungeonReward')):
if player == self.player and (item not in item_table or item_table[item][2] is None):
all_state.prog_items[(item, player)] = 0
# Remove all events and checked locations
all_state.locations_checked = {loc for loc in all_state.locations_checked if loc.player != self.player}
@ -1152,3 +1227,63 @@ class OOTWorld(World):
def get_filler_item_name(self) -> str:
return get_junk_item(count=1, pool=get_junk_pool(self))[0]
def valid_dungeon_item_location(world: OOTWorld, option: str, dungeon: str, loc: OOTLocation) -> bool:
if option == 'dungeon':
return (getattr(loc.parent_region.dungeon, 'name', None) == dungeon
and (world.shuffle_song_items != 'dungeon' or loc.name not in dungeon_song_locations))
elif option == 'any_dungeon':
return (loc.parent_region.dungeon is not None
and (world.shuffle_song_items != 'dungeon' or loc.name not in dungeon_song_locations))
elif option == 'overworld':
return (loc.parent_region.dungeon is None
and (loc.type != 'Shop' or loc.name in world.shop_prices)
and (world.shuffle_song_items != 'song' or loc.type != 'Song')
and (world.shuffle_song_items != 'dungeon' or loc.name not in dungeon_song_locations))
elif option == 'regional':
color = HintArea.for_dungeon(dungeon).color
return (HintArea.at(loc).color == color
and (loc.type != 'Shop' or loc.name in world.shop_prices)
and (world.shuffle_song_items != 'song' or loc.type != 'Song')
and (world.shuffle_song_items != 'dungeon' or loc.name not in dungeon_song_locations))
return False
# raise ValueError(f'Unexpected argument to valid_dungeon_item_location: {option}')
def gather_locations(multiworld: MultiWorld,
item_type: str,
players: Union[int, AbstractSet[int]],
dungeon: str = ''
) -> Optional[List[OOTLocation]]:
type_to_setting = {
'Song': 'shuffle_song_items',
'Map': 'shuffle_mapcompass',
'Compass': 'shuffle_mapcompass',
'SmallKey': 'shuffle_smallkeys',
'BossKey': 'shuffle_bosskeys',
'HideoutSmallKey': 'shuffle_hideoutkeys',
'GanonBossKey': 'shuffle_ganon_bosskey',
}
if isinstance(players, int):
players = {players}
fill_opts = {p: getattr(multiworld.worlds[p], type_to_setting[item_type]) for p in players}
locations = []
if item_type == 'Song':
if any(map(lambda v: v == 'any', fill_opts.values())):
return None
for player, option in fill_opts.items():
if option == 'song':
condition = lambda location: location.type == 'Song'
elif option == 'dungeon':
condition = lambda location: location.name in dungeon_song_locations
locations += filter(condition, multiworld.get_unfilled_locations(player=player))
else:
if any(map(lambda v: v in {'keysanity'}, fill_opts.values())):
return None
for player, option in fill_opts.items():
condition = functools.partial(valid_dungeon_item_location,
multiworld.worlds[player], option, dungeon)
locations += filter(condition, multiworld.get_unfilled_locations(player=player))
return locations

View File

@ -0,0 +1,3 @@
{
# This is a placeholder until Glitch 2.0 logic happens and boss shuffle is supported by it.
}

View File

@ -31,7 +31,7 @@
"region_name": "Deku Tree Boss Room",
"dungeon": "Deku Tree",
"events": {
"Deku Tree Clear": "Buy_Deku_Shield and (Kokiri_Sword or Sticks)"
"Deku Tree Clear": "Deku_Shield and (Kokiri_Sword or Sticks)"
},
"locations": {
"Deku Tree MQ Before Spinning Log Chest": "True",
@ -39,8 +39,8 @@
"Deku Tree MQ GS Basement Graves Room": "Boomerang and can_play(Song_of_Time)",
"Deku Tree MQ GS Basement Back Room": "Boomerang",
"Deku Tree MQ Deku Scrub": "True",
"Deku Tree Queen Gohma Heart": "Buy_Deku_Shield and (Kokiri_Sword or Sticks)",
"Queen Gohma": "Buy_Deku_Shield and (Kokiri_Sword or Sticks)"
"Deku Tree Queen Gohma Heart": "Deku_Shield and (Kokiri_Sword or Sticks)",
"Queen Gohma": "Deku_Shield and (Kokiri_Sword or Sticks)"
},
"exits": {
"Deku Tree Lobby": "True"

View File

@ -22,7 +22,7 @@
},
"exits": {
"Deku Tree Slingshot Room": "here(has_shield)",
"Deku Tree Boss Room": "here(has_fire_source_with_torch()) or can_shield
"Deku Tree Boss Door": "here(has_fire_source_with_torch()) or can_shield
or is_adult"
}
},
@ -38,7 +38,15 @@
}
},
{
"region_name": "Deku Tree Boss Room",
"region_name": "Deku Tree Boss Door",
"scene": "Deku Tree",
"dungeon": "Deku Tree",
"exits": {
"Queen Gohma Boss Room": "True"
}
},
{
"region_name": "Queen Gohma Boss Room",
"dungeon": "Deku Tree",
"events": {
"Deku Tree Clear": "(Nuts or can_use(Slingshot) or has_bombchus or can_use(Hookshot) or can_use(Bow) or can_use(Boomerang)) and

View File

@ -44,11 +44,11 @@
"Dodongos Cavern Gossip Stone": "True"
},
"exits": {
"Dodongos Cavern Boss Area": "has_explosives"
"King Dodongo Boss Room": "has_explosives"
}
},
{
"region_name": "Dodongos Cavern Boss Area",
"region_name": "King Dodongo Boss Room",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Under Grave Chest": "True",

View File

@ -63,12 +63,20 @@
or (can_live_dmg(0.5) and can_use(Hover_Boots)) or can_hover"
},
"exits": {
"Dodongos Cavern Boss Area": "has_explosives",
"Dodongos Cavern Boss Door": "has_explosives",
"Dodongos Cavern Lobby": "True"
}
},
{
"region_name": "Dodongos Cavern Boss Area",
"region_name": "Dodongos Cavern Boss Door",
"scene": "Dodongos Cavern",
"dungeon": "Dodongos Cavern",
"exits": {
"King Dodongo Boss Room": "True"
}
},
{
"region_name": "King Dodongo Boss Room",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Boss Room Chest": "True",

View File

@ -8,17 +8,12 @@
((Small_Key_Fire_Temple, 8) or not keysanity) and (can_use(Megaton_Hammer) or can_use(Hookshot) or has_explosives)",
"Fire Temple Boss Key Chest": "(
((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)) or (can_mega and can_use(Hookshot))",
"Fire Temple Volvagia Heart": "
(can_use(Goron_Tunic) or (Fairy and has_explosives)) and can_use(Megaton_Hammer) and
(Boss_Key_Fire_Temple or at('Fire Temple Flame Maze', True))",
"Volvagia": "
(can_use(Goron_Tunic) or (Fairy and has_explosives)) and can_use(Megaton_Hammer) and
(Boss_Key_Fire_Temple or at('Fire Temple Flame Maze', True))",
"Fire Temple GS Boss Key Loop": "
((Small_Key_Fire_Temple, 8) or not keysanity)"
},
"exits": {
"Fire Temple Big Lava Room":"(Small_Key_Fire_Temple, 2)"
"Fire Temple Big Lava Room":"(Small_Key_Fire_Temple, 2)",
"Fire Temple Boss Door": "True"
}
},
{
@ -92,5 +87,24 @@
"Fire Temple Megaton Hammer Chest": "has_explosives or
can_use(Megaton_Hammer)"
}
},
{
"region_name": "Fire Temple Boss Door",
"scene": "Fire Temple",
"dungeon": "Fire Temple",
"exits": {
"Volvagia Boss Room": "(Boss_Key_Fire_Temple or at('Fire Temple Flame Maze', True))"
}
},
{
"region_name": "Volvagia Boss Room",
"scene": "Fire Temple",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Volvagia Heart": "
(can_use(Goron_Tunic) or (Fairy and has_explosives)) and can_use(Megaton_Hammer)",
"Volvagia": "
(can_use(Goron_Tunic) or (Fairy and has_explosives)) and can_use(Megaton_Hammer)"
}
}
]

View File

@ -19,7 +19,7 @@
"Forest Temple Block Push Room": "(Small_Key_Forest_Temple, 1)",
"Forest Temple Basement": "(Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg) or (can_use(Hover_Boots) and can_mega)",
"Forest Temple Falling Room": "can_hover or (can_use(Hover_Boots) and Bombs and can_live_dmg(0.5))",
"Forest Temple Boss Room": "is_adult"
"Forest Temple Boss Door": "is_adult"
}
},
{
@ -34,10 +34,10 @@
"Forest Temple Outdoors High Balconies": "
is_adult or
(has_explosives or
((can_use(Boomerang) or Nuts or Buy_Deku_Shield) and
((can_use(Boomerang) or Nuts or Deku_Shield) and
(Sticks or Kokiri_Sword or can_use(Slingshot))))",
"Forest Temple Outside Upper Ledge": "can_hover or (can_use(Hover_Boots) and has_explosives and can_live_dmg(0.5))",
"Forest Temple Boss Room": "is_child and can_live_dmg(0.5)"
"Forest Temple Boss Door": "is_child and can_live_dmg(0.5)"
}
},
{
@ -147,11 +147,19 @@
"Forest Temple GS Basement": "can_use(Hookshot) or can_use(Boomerang) or can_hover"
},
"exits":{
"Forest Temple Boss Room": "Boss_Key_Forest_Temple"
"Forest Temple Boss Door": "Boss_Key_Forest_Temple"
}
},
{
"region_name": "Forest Temple Boss Room",
"region_name": "Forest Temple Boss Door",
"scene": "Forest Temple",
"dungeon": "Forest Temple",
"exits": {
"Phantom Ganon Boss Room": "True"
}
},
{
"region_name": "Phantom Ganon Boss Room",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Phantom Ganon Heart": "(can_use(Hookshot) or can_use(Bow)) or

View File

@ -31,11 +31,19 @@
},
"exits": {
"Jabu Jabus Belly Main": "True",
"Jabu Jabus Belly Boss Area": "can_use(Boomerang) or can_use(Hover_Boots) or can_mega"
"Jabu Jabus Belly Boss Door": "can_use(Boomerang) or can_use(Hover_Boots) or can_mega"
}
},
{
"region_name": "Jabu Jabus Belly Boss Area",
"region_name": "Jabu Jabus Belly Boss Door",
"scene": "Jabu Jabus Belly",
"dungeon": "Jabu Jabus Belly",
"exits": {
"Barinade Boss Room": "True"
}
},
{
"region_name": "Barinade Boss Room",
"dungeon": "Jabu Jabus Belly",
"locations": {
"Jabu Jabus Belly Barinade Heart": "can_use(Boomerang) and (Sticks or Kokiri_Sword)",

View File

@ -1,21 +1,22 @@
[
{
"region_name": "Root",
"hint": "Link's Pocket",
"hint": "ROOT",
"locations": {
"Links Pocket": "True"
"Links Pocket": "True",
"Gift from Sages": "can_receive_ganon_bosskey"
},
"exits": {
"Root Exits": "is_starting_age or Time_Travel",
"HC Garden Locations": "skip_child_zelda"
"HC Garden Locations": "shuffle_child_trade == 'skip_child_zelda'"
}
},
{
"region_name": "Root Exits",
"exits": {
"KF Links House": "is_child and (starting_age == 'child' or Time_Travel)",
"KF Links House": "is_child",
"Temple of Time": "
(is_adult and (starting_age == 'adult' or Time_Travel)) or
is_adult or
(can_play(Prelude_of_Light) and can_leave_forest)",
"Sacred Forest Meadow": "can_play(Minuet_of_Forest)",
"DMC Central": "can_play(Bolero_of_Fire) and can_leave_forest",
@ -26,9 +27,9 @@
},
{
"region_name": "Kokiri Forest",
"hint": "Kokiri Forest",
"hint": "KOKIRI_FOREST",
"events": {
"Showed Mido Sword & Shield": "open_forest == 'open' or (is_child and Kokiri_Sword and Buy_Deku_Shield)"
"Showed Mido Sword & Shield": "open_forest == 'open' or (is_child and Kokiri_Sword and Deku_Shield)"
},
"locations": {
"KF Kokiri Sword Chest": "is_child",
@ -58,7 +59,7 @@
},
{
"region_name": "KF Outside Deku Tree",
"hint": "Kokiri Forest",
"hint": "KOKIRI_FOREST",
"locations": {
"Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang",
"Deku Baba Nuts": "
@ -75,7 +76,7 @@
},
{
"region_name": "KF Links House",
"hint": "Kokiri Forest",
"hint": "KOKIRI_FOREST",
"locations": {
"KF Links House Cow": "is_adult and can_play(Eponas_Song) and 'Links Cow'"
},
@ -116,7 +117,7 @@
},
{
"region_name": "Lost Woods",
"hint": "the Lost Woods",
"hint": "LOST_WOODS",
"locations": {
"LW Skull Kid": "is_child and can_play(Sarias_Song)",
"LW Ocarina Memory Game": "is_child and Ocarina",
@ -137,14 +138,14 @@
},
{
"region_name": "LW Beyond Mido",
"hint": "the Lost Woods",
"hint": "LOST_WOODS",
"locations": {
"LW Deku Scrub Near Deku Theater Right": "is_child and can_stun_deku",
"LW Deku Scrub Near Deku Theater Left": "is_child and can_stun_deku",
"LW GS Above Theater": "is_adult and at_night and (here(can_plant_bean) or can_use(Longshot) or (has_bombchus and Progressive_Hookshot) or can_hover)",
"LW GS Bean Patch Near Theater": "
can_plant_bugs and
(can_child_attack or (shuffle_scrubs == 'off' and Buy_Deku_Shield))"
(can_child_attack or (shuffle_scrubs == 'off' and Deku_Shield))"
},
"exits": {
"Lost Woods": "True",
@ -155,7 +156,7 @@
},
{
"region_name": "SFM Entryway",
"hint": "Sacred Forest Meadow",
"hint": "SACRED_FOREST_MEADOW",
"exits": {
"LW Beyond Mido": "True",
"Sacred Forest Meadow": "
@ -166,7 +167,7 @@
},
{
"region_name": "Sacred Forest Meadow",
"hint": "Sacred Forest Meadow",
"hint": "SACRED_FOREST_MEADOW",
"locations": {
"Song from Saria": "is_child and Zeldas_Letter",
"Sheik in Forest": "is_adult",
@ -184,7 +185,7 @@
},
{
"region_name": "LW Bridge",
"hint": "the Lost Woods",
"hint": "LOST_WOODS",
"locations": {
"LW Gift from Saria": "True"
},
@ -195,7 +196,7 @@
},
{
"region_name": "Hyrule Field",
"hint": "Hyrule Field",
"hint": "HYRULE_FIELD",
"time_passes": true,
"locations": {
"HF Ocarina of Time Item": "is_child and has_all_stones",
@ -223,7 +224,7 @@
},
{
"region_name": "Lake Hylia",
"hint": "Lake Hylia",
"hint": "LAKE_HYLIA",
"time_passes": true,
"events": {
"Bonooru": "is_child and Ocarina"
@ -276,7 +277,7 @@
},
{
"region_name": "Gerudo Valley",
"hint": "Gerudo Valley",
"hint": "GERUDO_VALLEY",
"time_passes": true,
"locations": {
"GV Waterfall Freestanding PoH": "True",
@ -297,7 +298,7 @@
},
{
"region_name": "GV Fortress Side",
"hint": "Gerudo Valley",
"hint": "GERUDO_VALLEY",
"time_passes": true,
"locations": {
"GV Chest": "can_use(Megaton_Hammer)",
@ -311,9 +312,19 @@
},
{
"region_name": "Gerudo Fortress",
"hint": "Gerudo's Fortress",
"hint": "GERUDO_FORTRESS",
"events": {
"Carpenter Rescue": "can_finish_GerudoFortress",
"Hideout 1 Torch Jail Gerudo": "is_adult or (is_child and can_child_damage)",
"Hideout 2 Torches Jail Gerudo": "is_adult or (is_child and can_child_damage)",
"Hideout 3 Torches Jail Gerudo": "is_adult or (is_child and can_child_damage)",
"Hideout 4 Torches Jail Gerudo": "is_adult or (is_child and can_child_damage)",
"Hideout 1 Torch Jail Carpenter": "
'Hideout 1 Torch Jail Gerudo' and
((gerudo_fortress == 'normal' and (Small_Key_Thieves_Hideout, 4))
or (gerudo_fortress == 'fast' and Small_Key_Thieves_Hideout))",
"Hideout 2 Torches Jail Carpenter": "'Hideout 2 Torches Jail Gerudo' and gerudo_fortress == 'normal' and (Small_Key_Thieves_Hideout, 4)",
"Hideout 3 Torches Jail Carpenter": "'Hideout 3 Torches Jail Gerudo' and gerudo_fortress == 'normal' and (Small_Key_Thieves_Hideout, 4)",
"Hideout 4 Torches Jail Carpenter": "'Hideout 4 Torches Jail Gerudo' and gerudo_fortress == 'normal' and (Small_Key_Thieves_Hideout, 4)",
"GF Gate Open": "is_adult and Gerudo_Membership_Card"
},
"locations": {
@ -324,10 +335,10 @@
Gerudo_Membership_Card and can_ride_epona and Bow and is_adult",
"GF HBA 1500 Points": "
Gerudo_Membership_Card and can_ride_epona and Bow and is_adult",
"Hideout Jail Guard (1 Torch)": "is_adult or (is_child and can_child_damage)",
"Hideout Jail Guard (2 Torches)": "is_adult or (is_child and can_child_damage)",
"Hideout Jail Guard (3 Torches)": "is_adult or (is_child and can_child_damage)",
"Hideout Jail Guard (4 Torches)": "is_adult or (is_child and can_child_damage)",
"Hideout 1 Torch Jail Gerudo Key": "'Hideout 1 Torch Jail Gerudo'",
"Hideout 2 Torches Jail Gerudo Key": "'Hideout 2 Torches Jail Gerudo'",
"Hideout 3 Torches Jail Gerudo Key": "'Hideout 3 Torches Jail Gerudo'",
"Hideout 4 Torches Jail Gerudo Key": "'Hideout 4 Torches Jail Gerudo'",
"Hideout Gerudo Membership Card": "can_finish_GerudoFortress",
"GF GS Archery Range": "can_use(Hookshot) and at_night",
"GF GS Top Floor": "at_night and is_adult"
@ -340,7 +351,7 @@
},
{
"region_name": "Haunted Wasteland",
"hint": "Haunted Wasteland",
"hint": "HAUNTED_WASTELAND",
"locations": {
"Wasteland Chest": "has_fire_source",
"Wasteland Bombchu Salesman": "Progressive_Wallet and can_jumpslash",
@ -353,7 +364,7 @@
},
{
"region_name": "Desert Colossus",
"hint": "Desert Colossus",
"hint": "DESERT_COLOSSUS",
"time_passes": true,
"locations": {
"Colossus Freestanding PoH": "
@ -381,7 +392,7 @@
},
{
"region_name": "Market",
"hint": "the Market",
"hint": "MARKET",
"locations": {
"ToT Gossip Stone (Left)": "True",
"ToT Gossip Stone (Left-Center)": "True",
@ -407,9 +418,11 @@
},
{
"region_name": "Temple of Time",
"hint": "Temple of Time",
"hint": "TEMPLE_OF_TIME",
"locations": {
"ToT Light Arrows Cutscene": "is_adult and can_trigger_lacs"
"ToT Light Arrows Cutscene": "is_adult and can_trigger_lacs",
"ToT Child Altar Hint": "is_child",
"ToT Adult Altar Hint": "is_adult"
},
"exits": {
"Market": "True",
@ -419,7 +432,7 @@
},
{
"region_name": "Beyond Door of Time",
"hint": "Temple of Time",
"hint": "TEMPLE_OF_TIME",
"locations": {
"Master Sword Pedestal": "True",
"Sheik at Temple": "Forest_Medallion and is_adult"
@ -430,7 +443,7 @@
},
{
"region_name": "Hyrule Castle Grounds",
"hint": "Hyrule Castle",
"hint": "HYRULE_CASTLE",
"time_passes": true,
"locations": {
"HC Malon Egg": "True",
@ -441,14 +454,14 @@
"exits": {
"Market": "True",
#// garden will logically need weird-egg as letter first can screw over the mask quest
"HC Garden": "Weird_Egg or skip_child_zelda or (not shuffle_weird_egg)",
"HC Garden": "Weird_Egg",
"HC Great Fairy Fountain": "True",
"HC Storms Grotto": "can_play(Song_of_Storms)"
}
},
{
"region_name": "HC Garden",
"hint": "Hyrule Castle",
"hint": "HYRULE_CASTLE",
"exits": {
"HC Garden Locations": "True",
"Hyrule Castle Grounds": "True"
@ -457,7 +470,7 @@
{
# Directly reachable from Root in "Free Zelda"
"region_name": "HC Garden Locations",
"hint": "Hyrule Castle",
"hint": "HYRULE_CASTLE",
"locations": {
"HC Zeldas Letter": "True",
"Song from Impa": "True"
@ -471,7 +484,7 @@
},
{
"region_name": "Ganons Castle Grounds",
"hint": "outside Ganon's Castle",
"hint": "OUTSIDE_GANONS_CASTLE",
"locations": {
"OGC GS": "True"
},
@ -580,7 +593,7 @@
},
{
"region_name": "Kakariko Village",
"hint": "Kakariko Village",
"hint": "KAKARIKO_VILLAGE",
"locations": {
"Kak Man on Roof": "True",
"Kak Anju as Adult": "is_adult",
@ -589,7 +602,7 @@
is_adult and Forest_Medallion and Fire_Medallion and Water_Medallion",
"Kak GS House Under Construction": "is_child and at_night",
"Kak GS Skulltula House": "is_child and at_night",
"Kak GS Guards House": "is_child and at_night",
"Kak GS Near Gate Guard": "is_child and at_night",
"Kak GS Tree": "is_child and at_night",
"Kak GS Watchtower": "at_night and
is_child and (Slingshot or has_bombchus or
@ -631,7 +644,12 @@
"Kak 20 Gold Skulltula Reward": "(Gold_Skulltula_Token, 20)",
"Kak 30 Gold Skulltula Reward": "(Gold_Skulltula_Token, 30)",
"Kak 40 Gold Skulltula Reward": "(Gold_Skulltula_Token, 40)",
"Kak 50 Gold Skulltula Reward": "(Gold_Skulltula_Token, 50)"
"Kak 50 Gold Skulltula Reward": "(Gold_Skulltula_Token, 50)",
"10 Skulltulas Reward Hint": "True",
"20 Skulltulas Reward Hint": "True",
"30 Skulltulas Reward Hint": "True",
"40 Skulltulas Reward Hint": "True",
"50 Skulltulas Reward Hint": "True"
}
},
{
@ -646,7 +664,7 @@
},
{
"region_name": "Kak Windmill",
"hint": "Kakariko Village",
"hint": "KAKARIKO_VILLAGE",
"events": {
"Drain Well": "is_child and can_play(Song_of_Storms)"
},
@ -676,7 +694,7 @@
},
{
"region_name": "Kak Potion Shop Front",
"hint": "Kakariko Village",
"hint": "KAKARIKO_VILLAGE",
"locations": {
"Kak Potion Shop Item 1": "True",
"Kak Potion Shop Item 2": "True",
@ -696,7 +714,7 @@
},
{
"region_name": "Graveyard",
"hint": "the Graveyard",
"hint": "GRAVEYARD",
"locations": {
"Graveyard Freestanding PoH": "
(is_adult and here(can_plant_bean)) or
@ -739,19 +757,22 @@
},
{
"region_name": "Graveyard Dampes Grave",
"hint": "the Graveyard",
"hint": "GRAVEYARD",
"locations": {
"Graveyard Hookshot Chest": "True",
"Graveyard Dampe Race Hookshot Chest": "True",
"Graveyard Dampe Race Freestanding PoH": "True",
"Nut Pot": "True"
}
},
{
"region_name": "Graveyard Dampes House"
"region_name": "Graveyard Dampes House",
"locations": {
"Dampe Diary Hint": "is_adult"
}
},
{
"region_name": "Graveyard Warp Pad Region",
"hint": "the Graveyard",
"hint": "GRAVEYARD",
"locations": {
"Graveyard Gossip Stone": "True"
},
@ -762,7 +783,7 @@
},
{
"region_name": "Death Mountain",
"hint": "Death Mountain Trail",
"hint": "DEATH_MOUNTAIN_TRAIL",
"time_passes": true,
"locations": {
"DMT Chest": "
@ -789,7 +810,7 @@
},
{
"region_name": "Death Mountain Summit",
"hint": "Death Mountain Trail",
"hint": "DEATH_MOUNTAIN_TRAIL",
"time_passes": true,
"locations": {
"DMT Biggoron": "
@ -817,7 +838,7 @@
},
{
"region_name": "Goron City",
"hint": "Goron City",
"hint": "GORON_CITY",
"events": {
"GC Woods Warp Open": "
can_blast_or_smash or can_use(Dins_Fire) or can_use(Bow) or Progressive_Strength_Upgrade"
@ -881,7 +902,7 @@
{
"region_name": "GC Darunias Chamber",
"hint": "Goron City",
"hint": "GORON_CITY",
"events": {
"GC Woods Warp Open": "is_child and Sticks"
},
@ -910,7 +931,7 @@
},
{
"region_name": "DMC Upper",
"hint": "Death Mountain Crater",
"hint": "DEATH_MOUNTAIN_CRATER",
"locations": {
"DMC Wall Freestanding PoH": "True",
"DMC GS Crate": "
@ -930,7 +951,7 @@
},
{
"region_name": "DMC Lower",
"hint": "Death Mountain Crater",
"hint": "DEATH_MOUNTAIN_CRATER",
"exits": {
"GC Darunias Chamber": "True",
"DMC Great Fairy Fountain": "can_use(Megaton_Hammer) or can_mega or is_child",
@ -942,7 +963,7 @@
},
{
"region_name": "DMC Central",
"hint": "Death Mountain Crater",
"hint": "DEATH_MOUNTAIN_CRATER",
"locations": {
"DMC Volcano Freestanding PoH": "
(is_adult and here(can_plant_bean)) or
@ -971,7 +992,7 @@
},
{
"region_name": "ZR Front",
"hint": "Zora's River",
"hint": "ZORA_RIVER",
"time_passes": true,
"locations": {
"ZR GS Tree": "is_child and can_child_attack"
@ -983,7 +1004,7 @@
},
{
"region_name": "Zora River",
"hint": "Zora's River",
"hint": "ZORA_RIVER",
"time_passes": true,
"locations": {
"ZR Magic Bean Salesman": "is_child",
@ -991,6 +1012,11 @@
is_child and can_play(Zeldas_Lullaby) and can_play(Sarias_Song) and
can_play(Suns_Song) and can_play(Eponas_Song) and
can_play(Song_of_Time) and can_play(Song_of_Storms)",
"ZR Frogs Zeldas Lullaby": "is_child and can_play(Zeldas_Lullaby)",
"ZR Frogs Eponas Song": "is_child and can_play(Eponas_Song)",
"ZR Frogs Sarias Song": "is_child and can_play(Sarias_Song)",
"ZR Frogs Suns Song": "is_child and can_play(Suns_Song)",
"ZR Frogs Song of Time": "is_child and can_play(Song_of_Time)",
"ZR Frogs in the Rain": "is_child and can_play(Song_of_Storms)",
"ZR Near Open Grotto Freestanding PoH": "True",
"ZR Near Domain Freestanding PoH": "True",
@ -1011,7 +1037,7 @@
},
{
"region_name": "Zoras Domain",
"hint": "Zora's Domain",
"hint": "ZORAS_DOMAIN",
"locations": {
"ZD Diving Minigame": "is_child",
"ZD Chest": "can_use(Sticks)",
@ -1036,7 +1062,7 @@
},
{
"region_name": "Zoras Fountain",
"hint": "Zora's Fountain",
"hint": "ZORAS_FOUNTAIN",
"locations": {
"ZF Iceberg Freestanding PoH": "is_adult",
"ZF Bottom Freestanding PoH": "is_adult and Iron_Boots",
@ -1079,7 +1105,7 @@
},
{
"region_name": "Lon Lon Ranch",
"hint": "Lon Lon Ranch",
"hint": "LON_LON_RANCH",
"events": {
"Epona": "(can_play(Eponas_Song) or can_hover) and is_adult",
"Links Cow": "(can_play(Eponas_Song) or can_hover) and is_adult"

View File

@ -16,7 +16,7 @@
"exits": {
"Shadow Temple Entryway": "True",
"Shadow Temple First Beamos": "can_use(Hover_Boots) or can_mega",
"Shadow Boss": "can_hover and has_explosives and can_use(Hover_Boots) and
"Shadow Temple Boss Door": "can_hover and has_explosives and can_use(Hover_Boots) and
can_live_dmg(2.0)"
}
},
@ -45,7 +45,7 @@
"Shadow Temple Freestanding Key": "
(Small_Key_Shadow_Temple, 5) and (can_use(Hookshot) or can_hover)
and (Progressive_Strength_Upgrade or has_explosives)",
"Shadow Temple GS Like Like Room": "is_adult or can_use(Boomerang) or can_hover",
"Shadow Temple GS Invisible Blades Room": "is_adult or can_use(Boomerang) or can_hover",
"Shadow Temple GS Falling Spikes Room": "can_use(Hookshot) or (is_adult and can_mega) or (is_child and can_hover)",
"Shadow Temple GS Single Giant Pot": "(Small_Key_Shadow_Temple, 5) and (can_use(Hookshot) or can_hover)"
},
@ -91,14 +91,22 @@
"Shadow Temple GS Triple Giant Pot": "True"
},
"exits": {
"Shadow Boss": "(has_bombchus or can_use(Distant_Scarecrow) or Bow or
"Shadow Temple Boss Door": "(has_bombchus or can_use(Distant_Scarecrow) or Bow or
(can_mega and can_use(Hover_Boots)) or can_hover) and
(Boss_Key_Shadow_Temple or (has_explosives and is_adult)) and
(can_mega or can_use(Hover_Boots)) and (Small_Key_Shadow_Temple, 5)"
}
},
{
"region_name": "Shadow Boss",
"region_name": "Shadow Temple Boss Door",
"scene": "Shadow Temple",
"dungeon": "Shadow Temple",
"exits": {
"Bongo Bongo Boss Room": "True"
}
},
{
"region_name": "Bongo Bongo Boss Room",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Bongo Bongo Heart": "True",

View File

@ -18,6 +18,13 @@
(Sticks or has_explosives or
( (Nuts or can_use(Boomerang)) and
(can_use(Kokiri_Sword) or Slingshot) ) ))",
"Deku Shield Pot": "
fix_broken_drops and
(is_adult or (
(can_use(Boomerang) or Slingshot or has_bombchus or can_mega) and
(Sticks or has_explosives or
( (Nuts or can_use(Boomerang)) and
(can_use(Kokiri_Sword) or Slingshot) ) )))",
"Spirit Temple Child Early Torches Chest": "(is_adult and has_fire_source) or
(has_fire_source_with_torch and (here(is_adult) or
(
@ -94,7 +101,7 @@
can_hover or
can_use(Hookshot)) and has_explosives",
"Child Spirit Temple Climb": "True",
"Spirit Temple Boss": "can_use(Hookshot) and can_live_dmg(0.5) and Mirror_Shield and has_explosives",
"Spirit Temple Boss Door": "can_use(Hookshot) and can_live_dmg(0.5) and Mirror_Shield and has_explosives",
"Early Adult Spirit Temple": "can_jumpslash or can_hover or can_use(Hookshot)"
}
},
@ -156,12 +163,20 @@
"Spirit Temple Topmost Chest": "can_use(Mirror_Shield)"
},
"exits": {
"Spirit Temple Boss": "can_use(Mirror_Shield)",
"Spirit Temple Boss Door": "can_use(Mirror_Shield)",
"Spirit Temple Central Chamber": "can_use(Mirror_Shield) or can_use(Hookshot)"
}
},
{
"region_name": "Spirit Temple Boss",
"region_name": "Spirit Temple Boss Door",
"scene": "Spirit Temple",
"dungeon": "Spirit Temple",
"exits": {
"Twinrova Boss Room": "True"
}
},
{
"region_name": "Twinrova Boss Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Twinrova Heart": "True",

View File

@ -5,7 +5,7 @@
"locations": {},
"exits": {
"High Alcove": "is_adult or can_hover",
"Boss Area": "can_use(Longshot) or can_hover or (can_use(Hover_Boots) and (can_mega or Megaton_Hammer))",
"Water Temple Boss Door": "can_use(Longshot) or can_hover or (can_use(Hover_Boots) and (can_mega or Megaton_Hammer))",
"Dark Link Area": "(at('High Alcove', can_play(Zeldas_Lullaby)) or
(can_use(Hover_Boots) and (can_mega or Megaton_Hammer)))
and (Small_Key_Water_Temple, 4)",
@ -29,7 +29,7 @@
"Boss Key Area": "is_adult and
(Small_Key_Water_Temple, 4)
and (can_use(Longshot) or can_hover or Hover_Boots)",
"Boss Area": "can_play(Zeldas_Lullaby) and can_use(Longshot)",
"Water Temple Boss Door": "can_play(Zeldas_Lullaby) and can_use(Longshot)",
"Water Temple Lobby": "can_play(Zeldas_Lullaby)"
}
@ -161,7 +161,15 @@
}
},
{
"region_name": "Boss Area",
"region_name": "Water Temple Boss Door",
"scene": "Water Temple",
"dungeon": "Water Temple",
"exits": {
"Morpha Boss Room": "True"
}
},
{
"region_name": "Morpha Boss Room",
"dungeon": "Water Temple",
"events": {
"Water Temple Clear": "can_jumpslash and (can_hover or Boss_Key_Water_Temple)"

View File

@ -10,19 +10,24 @@
"dungeons_barren_limit": 1,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 1},
"woth": {"order": 3, "weight": 3.5, "fixed": 0, "copies": 1},
"barren": {"order": 4, "weight": 2.0, "fixed": 0, "copies": 1},
"entrance": {"order": 5, "weight": 3.0, "fixed": 0, "copies": 1},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 7, "weight": 6.0, "fixed": 0, "copies": 1},
"item": {"order": 8, "weight": 5.0, "fixed": 0, "copies": 1},
"song": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1},
"overworld": {"order": 10, "weight": 2.0, "fixed": 0, "copies": 1},
"dungeon": {"order": 11, "weight": 1.5, "fixed": 0, "copies": 1},
"junk": {"order": 12, "weight": 3.0, "fixed": 0, "copies": 1},
"named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1}
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 1},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 1},
"woth": {"order": 4, "weight": 3.5, "fixed": 0, "copies": 1},
"barren": {"order": 5, "weight": 2.0, "fixed": 0, "copies": 1},
"entrance": {"order": 6, "weight": 3.0, "fixed": 0, "copies": 1},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 8, "weight": 6.0, "fixed": 0, "copies": 1},
"item": {"order": 9, "weight": 5.0, "fixed": 0, "copies": 1},
"song": {"order": 10, "weight": 1.0, "fixed": 0, "copies": 1},
"overworld": {"order": 11, "weight": 2.0, "fixed": 0, "copies": 1},
"dungeon": {"order": 12, "weight": 1.5, "fixed": 0, "copies": 1},
"junk": {"order": 13, "weight": 3.0, "fixed": 0, "copies": 1},
"named-item": {"order": 14, "weight": 0.0, "fixed": 0, "copies": 1},
"goal": {"order": 15, "weight": 0.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 16, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 17, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -10,19 +10,24 @@
"dungeons_barren_limit": 1,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 0},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 0},
"barren": {"order": 4, "weight": 0.0, "fixed": 0, "copies": 0},
"entrance": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 2},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 2},
"item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 12, "weight": 1.0, "fixed": 0, "copies": 1},
"named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 2}
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 0.0, "fixed": 0, "copies": 0},
"barren": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 0},
"entrance": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 2},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2},
"item": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 13, "weight": 1.0, "fixed": 0, "copies": 1},
"named-item": {"order": 14, "weight": 0.0, "fixed": 0, "copies": 2},
"goal": {"order": 15, "weight": 0.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 16, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 17, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -0,0 +1,33 @@
{
"name": "chaos",
"gui_name": "Chaos!!!",
"description": "A completely randomized hint distribution with single copies",
"add_locations": [],
"remove_locations": [],
"add_items": [],
"remove_items": [],
"dungeons_woth_limit": 40,
"dungeons_barren_limit": 40,
"named_items_required": false,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 1.0, "fixed": 0, "copies": 1},
"always": {"order": 2, "weight": 1.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 3, "weight": 1.0, "fixed": 0, "copies": 1},
"entrance_always": {"order": 4, "weight": 1.0, "fixed": 0, "copies": 1},
"woth": {"order": 5, "weight": 1.0, "fixed": 0, "copies": 1},
"goal": {"order": 6, "weight": 1.0, "fixed": 0, "copies": 1},
"barren": {"order": 7, "weight": 1.0, "fixed": 0, "copies": 1},
"item": {"order": 8, "weight": 1.0, "fixed": 0, "copies": 1},
"sometimes": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1},
"dual": {"order": 10, "weight": 1.0, "fixed": 0, "copies": 1},
"song": {"order": 11, "weight": 1.0, "fixed": 0, "copies": 1},
"overworld": {"order": 12, "weight": 1.0, "fixed": 0, "copies": 1},
"dungeon": {"order": 13, "weight": 1.0, "fixed": 0, "copies": 1},
"entrance": {"order": 14, "weight": 1.0, "fixed": 0, "copies": 1},
"random": {"order": 15, "weight": 1.0, "fixed": 0, "copies": 1},
"junk": {"order": 16, "weight": 1.0, "fixed": 0, "copies": 1},
"named-item": {"order": 17, "weight": 1.0, "fixed": 0, "copies": 1}
}
}

View File

@ -0,0 +1,38 @@
{
"name": "coop2",
"gui_name": "Co-op",
"description": "Tournament hints used for Season 2 Co-op Tournament Races.",
"add_locations": [
{ "location": "Deku Theater Skull Mask", "types": ["always"] },
{ "location": "DMC Deku Scrub", "types": ["always"] }
],
"remove_locations": [],
"add_items": [
{ "item": "Light Arrows", "types": ["named-item"] }
],
"remove_items": [],
"dungeons_woth_limit": 2,
"dungeons_barren_limit": 1,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 3},
"always": {"order": 3, "weight": 0.0, "fixed": 6, "copies": 3},
"junk": {"order": 4, "weight": 0.0, "fixed": 1, "copies": 1},
"barren": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 2},
"entrance": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 2},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 100, "copies": 3},
"random": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"named-item": {"order": 9, "weight": 0.0, "fixed": 1, "copies": 3},
"goal": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -33,19 +33,24 @@
"dungeons_barren_limit": 1,
"named_items_required": false,
"vague_named_items": true,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 0.0, "fixed": 2, "copies": 2},
"barren": {"order": 4, "weight": 0.0, "fixed": 3, "copies": 2},
"entrance": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 2},
"sometimes": {"order": 13,"weight": 0.0, "fixed": 99, "copies": 2},
"random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 2},
"item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 1},
"named-item": {"order": 6, "weight": 0.0, "fixed": 3, "copies": 2}
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 0.0, "fixed": 2, "copies": 2},
"barren": {"order": 5, "weight": 0.0, "fixed": 3, "copies": 2},
"entrance": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 2},
"sometimes": {"order": 14, "weight": 0.0, "fixed": 99, "copies": 2},
"random": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2},
"item": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1},
"named-item": {"order": 7, "weight": 0.0, "fixed": 3, "copies": 2},
"goal": {"order": 15, "weight": 0.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 16, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 17, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -1,31 +1,58 @@
{
"name": "league",
"gui_name": "League",
"description": "Hint Distro for the OoTR League",
"gui_name": "League S3",
"description": "Hint Distribution for the S3 of League. 5 Goal Hints, 3 Barren Hints, 5 Sometimes hints, 7 Always hints (including skull mask), Several hints removed from the Sometimes hint pool.",
"add_locations": [
{ "location": "Deku Theater Skull Mask", "types": ["always"] }
],
"remove_locations": [],
"remove_locations": [
{"location": "Sheik in Crater", "types": ["sometimes"]},
{"location": "Song from Royal Familys Tomb", "types": ["sometimes"]},
{"location": "Sheik in Forest", "types": ["sometimes"]},
{"location": "Sheik at Temple", "types": ["sometimes"]},
{"location": "Sheik at Colossus", "types": ["sometimes"]},
{"location": "LH Sun", "types": ["sometimes"]},
{"location": "GF HBA 1500 Points", "types": ["sometimes"]},
{"location": "GC Maze Left Chest", "types": ["sometimes"]},
{"location": "GV Chest", "types": ["sometimes"]},
{"location": "Graveyard Royal Familys Tomb Chest", "types": ["sometimes"]},
{"location": "GC Pot Freestanding PoH", "types": ["sometimes"]},
{"location": "LH Lab Dive", "types": ["sometimes"]},
{"location": "Fire Temple Megaton Hammer Chest", "types": ["sometimes"]},
{"location": "Water Temple Boss Key Chest", "types": ["sometimes"]},
{"location": "Gerudo Training Ground Maze Path Final Chest", "types": ["sometimes"]},
{"location": "Spirit Temple Silver Gauntlets Chest", "types": ["sometimes"]},
{"location": "Spirit Temple Mirror Shield Chest", "types": ["sometimes"]},
{"location": "Shadow Temple Freestanding Key", "types": ["sometimes"]},
{"location": "Ice Cavern Iron Boots Chest", "types": ["sometimes"]},
{"location": "Ganons Castle Shadow Trial Golden Gauntlets Chest", "types": ["sometimes"]}
],
"add_items": [],
"remove_items": [{"types": ["woth"], "item": "Zeldas Lullaby"}],
"remove_items": [
{ "item": "Zeldas Lullaby", "types": ["goal"] }
],
"dungeons_woth_limit": 2,
"dungeons_barren_limit": 1,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 0.0, "fixed": 5, "copies": 2},
"barren": {"order": 4, "weight": 0.0, "fixed": 3, "copies": 2},
"entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 2},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 100, "copies": 2},
"random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 2},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"goal": {"order": 4, "weight": 0.0, "fixed": 5, "copies": 2},
"barren": {"order": 5, "weight": 0.0, "fixed": 3, "copies": 2},
"entrance": {"order": 6, "weight": 0.0, "fixed": 4, "copies": 2},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 100, "copies": 2},
"random": {"order": 8, "weight": 9.0, "fixed": 0, "copies": 2},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2}
},
"groups": [],
"disabled": []
"named-item": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dual_always": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -1,143 +0,0 @@
{
"name": "mw2",
"gui_name": "MW Season 2",
"description": "Hints used for the multi-world tournament season 2.",
"add_locations": [
{
"location": "Song from Ocarina of Time",
"types": [
"always"
]
},
{
"location": "Deku Theater Skull Mask",
"types": [
"always"
]
},
{
"location": "DMC Deku Scrub",
"types": [
"always"
]
}
],
"remove_locations": [
{
"location": "Haunted Wasteland",
"types": [
"barren"
]
},
{
"location": "Temple of Time",
"types": [
"barren"
]
},
{
"location": "Hyrule Castle",
"types": [
"barren"
]
},
{
"location": "outside Ganon's Castle",
"types": [
"barren"
]
}
],
"add_items": [],
"remove_items": [
{
"item": "Zeldas Lullaby",
"types": [
"woth"
]
}
],
"dungeons_woth_limit": 3,
"dungeons_barren_limit": 1,
"named_items_required": true,
"distribution": {
"trial": {
"order": 1,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"always": {
"order": 2,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"woth": {
"order": 3,
"weight": 0.0,
"fixed": 7,
"copies": 2
},
"barren": {
"order": 4,
"weight": 0.0,
"fixed": 3,
"copies": 2
},
"entrance": {
"order": 5,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"sometimes": {
"order": 6,
"weight": 0.0,
"fixed": 100,
"copies": 2
},
"random": {
"order": 7,
"weight": 9.0,
"fixed": 0,
"copies": 2
},
"item": {
"order": 0,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"song": {
"order": 0,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"overworld": {
"order": 0,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"dungeon": {
"order": 0,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"junk": {
"order": 0,
"weight": 0.0,
"fixed": 0,
"copies": 2
},
"named-item": {
"order": 8,
"weight": 0.0,
"fixed": 0,
"copies": 2
}
}
}

View File

@ -0,0 +1,62 @@
{
"name": "mw3",
"gui_name": "MW Season 3",
"description": "Hints used for the Multiworld Tournament Season 3.",
"add_locations": [
{"location": "Sheik in Kakariko", "types": ["always"]},
{"location": "Song from Ocarina of Time", "types": ["always"]},
{"location": "Deku Theater Skull Mask", "types": ["always"]},
{"location": "DMC Deku Scrub", "types": ["always"]},
{"location": "Deku Tree GS Basement Back Room", "types": ["sometimes"]},
{"location": "Water Temple GS River", "types": ["sometimes"]},
{"location": "Spirit Temple GS Hall After Sun Block Room", "types": ["sometimes"]}
],
"remove_locations": [
{"location": "Sheik in Crater", "types": ["sometimes"]},
{"location": "Song from Royal Familys Tomb", "types": ["sometimes"]},
{"location": "Sheik in Forest", "types": ["sometimes"]},
{"location": "Sheik at Temple", "types": ["sometimes"]},
{"location": "Sheik at Colossus", "types": ["sometimes"]},
{"location": "LH Sun", "types": ["sometimes"]},
{"location": "GC Maze Left Chest", "types": ["sometimes"]},
{"location": "GV Chest", "types": ["sometimes"]},
{"location": "Graveyard Royal Familys Tomb Chest", "types": ["sometimes"]},
{"location": "GC Pot Freestanding PoH", "types": ["sometimes"]},
{"location": "LH Lab Dive", "types": ["sometimes"]},
{"location": "Fire Temple Megaton Hammer Chest", "types": ["sometimes"]},
{"location": "Fire Temple Scarecrow Chest", "types": ["sometimes"]},
{"location": "Water Temple Boss Key Chest", "types": ["sometimes"]},
{"location": "Water Temple GS Behind Gate", "types": ["sometimes"]},
{"location": "Gerudo Training Ground Maze Path Final Chest", "types": ["sometimes"]},
{"location": "Spirit Temple Silver Gauntlets Chest", "types": ["sometimes"]},
{"location": "Spirit Temple Mirror Shield Chest", "types": ["sometimes"]},
{"location": "Shadow Temple Freestanding Key", "types": ["sometimes"]},
{"location": "Ganons Castle Shadow Trial Golden Gauntlets Chest", "types": ["sometimes"]}
],
"add_items": [],
"remove_items": [
{"item": "Zeldas Lullaby", "types": ["woth","goal"]}
],
"dungeons_woth_limit": 40,
"dungeons_barren_limit": 40,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"upgrade_hints": "on",
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"goal": {"order": 3, "weight": 0.0, "fixed": 7, "copies": 2},
"sometimes": {"order": 4, "weight": 0.0, "fixed": 100, "copies": 2},
"barren": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"entrance": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"random": {"order": 0, "weight": 9.0, "fixed": 0, "copies": 2},
"woth": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"named-item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2}
}
}

View File

@ -1,32 +1,40 @@
{
"name": "scrubs",
"gui_name": "Scrubs",
"description": "Tournament hints used for Scrubs Races. Duplicates of each hint, Skull Mask is an always hint, 5 WotH, 3 Foolish, 8 sometimes. Can also be used to simulate S3 Tournament hints.",
"description": "Tournament hints used for Scrubs Races. Duplicates of each hint, Sheik at Temple is an always hint, 5 WotH, 5 Foolish, 6 sometimes.",
"add_locations": [
{ "location": "Sheik at Temple", "types": ["always"] },
{ "location": "Deku Theater Skull Mask", "types": ["always"] },
{ "location": "Deku Theater Mask of Truth", "types": ["always"] }
],
"remove_locations": [],
"add_items": [],
"remove_items": [],
"remove_items": [
{ "item": "Zeldas Lullaby", "types": ["woth"] }
],
"dungeons_woth_limit": 2,
"dungeons_barren_limit": 1,
"dungeons_barren_limit": 2,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 0.0, "fixed": 5, "copies": 2},
"barren": {"order": 4, "weight": 0.0, "fixed": 3, "copies": 2},
"entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 2},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 100, "copies": 2},
"random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 2},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 0.0, "fixed": 5, "copies": 2},
"barren": {"order": 5, "weight": 0.0, "fixed": 5, "copies": 2},
"entrance": {"order": 6, "weight": 0.0, "fixed": 3, "copies": 2},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 100, "copies": 2},
"random": {"order": 8, "weight": 9.0, "fixed": 0, "copies": 2},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2}
"named-item": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2},
"goal": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0}
},
"groups": [],
"disabled": []

View File

@ -10,19 +10,24 @@
"dungeons_barren_limit": 1,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.00, "fixed": 0, "copies": 1},
"always": {"order": 2, "weight": 0.00, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 3.00, "fixed": 0, "copies": 2},
"barren": {"order": 4, "weight": 3.00, "fixed": 0, "copies": 1},
"entrance": {"order": 5, "weight": 1.00, "fixed": 0, "copies": 1},
"sometimes": {"order": 6, "weight": 0.00, "fixed": 0, "copies": 1},
"random": {"order": 7, "weight": 2.00, "fixed": 0, "copies": 1},
"item": {"order": 8, "weight": 1.00, "fixed": 0, "copies": 1},
"song": {"order": 9, "weight": 0.33, "fixed": 0, "copies": 1},
"overworld": {"order": 10, "weight": 0.66, "fixed": 0, "copies": 1},
"dungeon": {"order": 11, "weight": 0.66, "fixed": 0, "copies": 1},
"junk": {"order": 12, "weight": 0.00, "fixed": 0, "copies": 1},
"named-item": {"order": 13, "weight": 0.00, "fixed": 0, "copies": 1}
"entrance_always": {"order": 2, "weight": 0.00, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.00, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 3.00, "fixed": 0, "copies": 2},
"barren": {"order": 5, "weight": 3.00, "fixed": 0, "copies": 1},
"entrance": {"order": 6, "weight": 1.00, "fixed": 0, "copies": 1},
"sometimes": {"order": 7, "weight": 0.00, "fixed": 0, "copies": 1},
"random": {"order": 8, "weight": 2.00, "fixed": 0, "copies": 1},
"item": {"order": 9, "weight": 1.00, "fixed": 0, "copies": 1},
"song": {"order": 10, "weight": 0.33, "fixed": 0, "copies": 1},
"overworld": {"order": 11, "weight": 0.66, "fixed": 0, "copies": 1},
"dungeon": {"order": 12, "weight": 0.66, "fixed": 0, "copies": 1},
"junk": {"order": 13, "weight": 0.00, "fixed": 0, "copies": 1},
"named-item": {"order": 14, "weight": 0.00, "fixed": 0, "copies": 1},
"goal": {"order": 15, "weight": 0.00, "fixed": 0, "copies": 1},
"dual_always": {"order": 16, "weight": 0.00, "fixed": 0, "copies": 0},
"dual": {"order": 17, "weight": 0.00, "fixed": 0, "copies": 0}
}
}

View File

@ -1,32 +1,43 @@
{
"name": "tournament",
"gui_name": "Tournament",
"description": "Tournament hints used for OoTR Season 4. Gossip stones in grottos are disabled. 4 WotH, 2 Barren, remainder filled with Sometimes. Always, WotH, and Barren hints duplicated.",
"add_locations": [],
"remove_locations": [],
"description": "Hint Distribution for the S6 Tournament. 5 Goal hints, 7 Sometimes hints, 8 Always hints (including Skull Mask and Sheik in Kakariko).",
"add_locations": [
{ "location": "Deku Theater Skull Mask", "types": ["always"] },
{ "location": "Sheik in Kakariko", "types": ["always"] }
],
"remove_locations": [
{ "location": "Ganons Castle Shadow Trial Golden Gauntlets Chest", "types": ["sometimes"] },
{ "location": "Sheik in Forest", "types": ["sometimes"] },
{ "location": "Sheik at Temple", "types": ["sometimes"] },
{ "location": "Sheik in Crater", "types": ["sometimes"] },
{ "location": "Sheik at Colossus", "types": ["sometimes"] },
{ "location": "Song from Royal Familys Tomb", "types": ["sometimes"] }
],
"add_items": [],
"remove_items": [{"types": ["woth"], "item": "Zeldas Lullaby"}],
"dungeons_woth_limit": 2,
"dungeons_barren_limit": 1,
"remove_items": [
{ "item": "Zeldas Lullaby", "types": ["goal"] }
],
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 0.0, "fixed": 4, "copies": 2},
"barren": {"order": 4, "weight": 0.0, "fixed": 2, "copies": 2},
"entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 1},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 99, "copies": 1},
"random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 1},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 1},
"named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 1}
},
"groups": [],
"disabled": [
"HC (Storms Grotto)", "HF (Cow Grotto)", "HF (Near Market Grotto)", "HF (Southeast Grotto)", "HF (Open Grotto)", "Kak (Open Grotto)", "ZR (Open Grotto)", "KF (Storms Grotto)", "LW (Near Shortcuts Grotto)", "DMT (Storms Grotto)", "DMC (Upper Grotto)"
]
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"goal": {"order": 4, "weight": 0.0, "fixed": 5, "copies": 2},
"barren": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"entrance": {"order": 5, "weight": 0.0, "fixed": 4, "copies": 2},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 100, "copies": 2},
"random": {"order": 7, "weight": 9.0, "fixed": 0, "copies": 2},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"named-item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dual_always": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -10,19 +10,24 @@
"dungeons_barren_limit": 1,
"named_items_required": false,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 0},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 0},
"woth": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 0},
"barren": {"order": 4, "weight": 0.0, "fixed": 0, "copies": 0},
"entrance": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 0},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 0},
"random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 0},
"item": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 0},
"song": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 0},
"overworld": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 0},
"dungeon": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 0},
"junk": {"order": 12, "weight": 9.0, "fixed": 0, "copies": 1},
"named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 0}
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 0},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 0},
"woth": {"order": 4, "weight": 0.0, "fixed": 0, "copies": 0},
"barren": {"order": 5, "weight": 0.0, "fixed": 0, "copies": 0},
"entrance": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 0},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 0},
"random": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 0},
"item": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 0},
"song": {"order": 10, "weight": 0.0, "fixed": 0, "copies": 0},
"overworld": {"order": 11, "weight": 0.0, "fixed": 0, "copies": 0},
"dungeon": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 0},
"junk": {"order": 13, "weight": 9.0, "fixed": 0, "copies": 1},
"named-item": {"order": 14, "weight": 0.0, "fixed": 0, "copies": 0},
"goal": {"order": 15, "weight": 0.0, "fixed": 0, "copies": 0},
"dual_always": {"order": 16, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 17, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -10,19 +10,24 @@
"dungeons_barren_limit": 40,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": true,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1},
"always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 3, "weight": 3.0, "fixed": 0, "copies": 2},
"barren": {"order": 4, "weight": 3.0, "fixed": 0, "copies": 1},
"entrance": {"order": 5, "weight": 2.0, "fixed": 0, "copies": 1},
"sometimes": {"order": 6, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 1},
"item": {"order": 8, "weight": 1.0, "fixed": 0, "copies": 1},
"song": {"order": 9, "weight": 0.5, "fixed": 0, "copies": 1},
"overworld": {"order": 10, "weight": 1.5, "fixed": 0, "copies": 1},
"dungeon": {"order": 11, "weight": 1.5, "fixed": 0, "copies": 1},
"junk": {"order": 12, "weight": 0.0, "fixed": 0, "copies": 1},
"named-item": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1}
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 3.0, "fixed": 0, "copies": 2},
"barren": {"order": 5, "weight": 3.0, "fixed": 0, "copies": 1},
"entrance": {"order": 6, "weight": 2.0, "fixed": 0, "copies": 1},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 1},
"item": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1},
"song": {"order": 10, "weight": 0.5, "fixed": 0, "copies": 1},
"overworld": {"order": 11, "weight": 1.5, "fixed": 0, "copies": 1},
"dungeon": {"order": 12, "weight": 1.5, "fixed": 0, "copies": 1},
"junk": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1},
"named-item": {"order": 14, "weight": 0.0, "fixed": 0, "copies": 1},
"goal": {"order": 15, "weight": 0.0, "fixed": 0, "copies": 1},
"dual_always": {"order": 16, "weight": 0.0, "fixed": 0, "copies": 0},
"dual": {"order": 17, "weight": 0.0, "fixed": 0, "copies": 0}
}
}

View File

@ -0,0 +1,47 @@
{
"name": "very_strong_magic",
"gui_name": "Very Strong with Magic",
"description": "Like the Very Strong hint distribution, but a fixed goal hint with two copies for a Magic Meter is added. All other goals are removed.",
"add_locations": [],
"remove_locations": [],
"add_items": [],
"remove_items": [],
"dungeons_woth_limit": 40,
"dungeons_barren_limit": 40,
"named_items_required": true,
"vague_named_items": false,
"use_default_goals": false,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 1},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 3.0, "fixed": 0, "copies": 2},
"barren": {"order": 5, "weight": 3.0, "fixed": 0, "copies": 1},
"entrance": {"order": 6, "weight": 2.0, "fixed": 0, "copies": 1},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 0, "copies": 1},
"random": {"order": 8, "weight": 0.0, "fixed": 0, "copies": 1},
"item": {"order": 9, "weight": 1.0, "fixed": 0, "copies": 1},
"song": {"order": 10, "weight": 0.5, "fixed": 0, "copies": 1},
"overworld": {"order": 11, "weight": 1.5, "fixed": 0, "copies": 1},
"dungeon": {"order": 12, "weight": 1.5, "fixed": 0, "copies": 1},
"junk": {"order": 13, "weight": 0.0, "fixed": 0, "copies": 1},
"named-item": {"order": 14, "weight": 0.0, "fixed": 0, "copies": 1},
"goal": {"order": 15, "weight": 0.0, "fixed": 1, "copies": 2}
},
"custom_goals": [
{
"category": "path_of_magic",
"priority": 90,
"minimum_goals": 1,
"lock_entrances" : [],
"goals": [
{
"name": "Magic",
"hint_text": "Path of Magic",
"color": "Green",
"items": [{"name": "Magic Meter", "quantity": 2, "minimum": 1, "hintable": true}]
}
]
}
]
}

View File

@ -0,0 +1,34 @@
{
"name": "weekly",
"gui_name": "Weekly",
"description": "Hint distribution used for weekly races. Duplicates of each hint, Skull Mask is an always hint, 5 WotH, 3 Foolish, 5 sometimes.",
"add_locations": [
{ "location": "Deku Theater Skull Mask", "types": ["always"] },
{ "location": "Deku Theater Mask of Truth", "types": ["always"] }
],
"remove_locations": [],
"add_items": [],
"remove_items": [
{ "item": "Zeldas Lullaby", "types": ["woth"] }
],
"dungeons_woth_limit": 2,
"dungeons_barren_limit": 1,
"named_items_required": true,
"vague_named_items": false,
"distribution": {
"trial": {"order": 1, "weight": 0.0, "fixed": 0, "copies": 2},
"entrance_always": {"order": 2, "weight": 0.0, "fixed": 0, "copies": 2},
"always": {"order": 3, "weight": 0.0, "fixed": 0, "copies": 2},
"woth": {"order": 4, "weight": 0.0, "fixed": 5, "copies": 2},
"barren": {"order": 5, "weight": 0.0, "fixed": 3, "copies": 2},
"entrance": {"order": 6, "weight": 0.0, "fixed": 4, "copies": 2},
"sometimes": {"order": 7, "weight": 0.0, "fixed": 100, "copies": 2},
"random": {"order": 8, "weight": 9.0, "fixed": 0, "copies": 2},
"item": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"song": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"overworld": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"dungeon": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"junk": {"order": 0, "weight": 0.0, "fixed": 0, "copies": 2},
"named-item": {"order": 9, "weight": 0.0, "fixed": 0, "copies": 2}
}
}

Binary file not shown.

View File

@ -20,12 +20,12 @@
# "Bow": "'Bow'",
# "Slingshot": "'Slingshot'",
"Bombs": "Bomb_Bag",
"Deku_Shield": "Buy_Deku_Shield",
"Deku_Shield": "Buy_Deku_Shield or Deku_Shield_Drop",
"Hylian_Shield": "Buy_Hylian_Shield",
"Nuts": "Buy_Deku_Nut_5 or Buy_Deku_Nut_10 or Deku_Nut_Drop",
"Sticks": "Buy_Deku_Stick_1 or Deku_Stick_Drop",
"Bugs": "'Bugs' or Buy_Bottle_Bug",
"Blue_Fire": "'Blue Fire' or Buy_Blue_Fire",
"Blue_Fire": "'Blue Fire' or Buy_Blue_Fire or (blue_fire_arrows and can_use(Ice_Arrows))",
"Fish": "'Fish' or Buy_Fish",
"Fairy": "'Fairy' or Buy_Fairys_Spirit",
"Big_Poe": "'Big Poe'",
@ -49,7 +49,7 @@
"can_summon_gossip_fairy": "Ocarina and (Zeldas_Lullaby or Eponas_Song or Song_of_Time or Suns_Song)",
"can_summon_gossip_fairy_without_suns": "Ocarina and (Zeldas_Lullaby or Eponas_Song or Song_of_Time)",
"can_take_damage": "damage_multiplier != 'ohko' or Fairy or can_use(Nayrus_Love)",
"can_plant_bean": "is_child and (Magic_Bean or Magic_Bean_Pack)",
"can_plant_bean": "plant_beans or (is_child and _oot_has_beans)",
"can_play(song)": "Ocarina and song",
"can_open_bomb_grotto": "can_blast_or_smash and (Stone_of_Agony or logic_grottos_without_agony)",
"can_open_storm_grotto": "can_play(Song_of_Storms) and (Stone_of_Agony or logic_grottos_without_agony)",
@ -61,7 +61,11 @@
or (for_age == adult and (Bow or Hookshot))
or (for_age == both and (Slingshot or Boomerang) and (Bow or Hookshot))
or (for_age == either and (Slingshot or Boomerang or Bow or Hookshot))",
"can_bonk": "deadly_bonks != 'ohko' or Fairy or can_use(Nayrus_Love)",
"can_break_crate": "can_bonk or can_blast_or_smash",
"can_break_heated_crate": "deadly_bonks != 'ohko' or (Fairy and (can_use(Goron_Tunic) or damage_multiplier != 'ohko')) or can_use(Nayrus_Love) or can_blast_or_smash",
"can_break_lower_beehive": "can_use(Boomerang) or can_use(Hookshot) or Bombs or (logic_beehives_bombchus and has_bombchus)",
"can_break_upper_beehive": "can_use(Boomerang) or can_use(Hookshot) or (logic_beehives_bombchus and has_bombchus)",
# can_use and helpers
# The parser reduces this to smallest form based on item category.
# Note that can_use(item) is False for any item not covered here.
@ -72,7 +76,7 @@
"_is_magic_item(item)": "item == Dins_Fire or item == Farores_Wind or item == Nayrus_Love or item == Lens_of_Truth",
"_is_adult_item(item)": "item == Bow or item == Megaton_Hammer or item == Iron_Boots or item == Hover_Boots or item == Hookshot or item == Longshot or item == Silver_Gauntlets or item == Golden_Gauntlets or item == Goron_Tunic or item == Zora_Tunic or item == Scarecrow or item == Distant_Scarecrow or item == Mirror_Shield",
"_is_child_item(item)": "item == Slingshot or item == Boomerang or item == Kokiri_Sword or item == Sticks or item == Deku_Shield",
"_is_magic_arrow(item)": "item == Fire_Arrows or item == Light_Arrows",
"_is_magic_arrow(item)": "item == Fire_Arrows or item == Light_Arrows or (blue_fire_arrows and item == Ice_Arrows)",
# Biggoron's trade path
# ER with certain settings disables timers and prevents items from reverting on save warp.
@ -83,8 +87,10 @@
"has_fire_source_with_torch": "has_fire_source or (is_child and Sticks)",
# Gerudo Fortress
"can_finish_GerudoFortress": "(gerudo_fortress == 'normal' and (Small_Key_Thieves_Hideout, 4) and (is_adult or Kokiri_Sword or is_glitched) and (is_adult and (Bow or Hookshot or Hover_Boots) or Gerudo_Membership_Card or logic_gerudo_kitchen or is_glitched))
or (gerudo_fortress == 'fast' and Small_Key_Thieves_Hideout and (is_adult or Kokiri_Sword or is_glitched))
"can_finish_GerudoFortress": "(gerudo_fortress == 'normal' and
'Hideout 1 Torch Jail Carpenter' and 'Hideout 2 Torches Jail Carpenter'
and 'Hideout 3 Torches Jail Carpenter' and 'Hideout 4 Torches Jail Carpenter')
or (gerudo_fortress == 'fast' and 'Hideout 1 Torch Jail Carpenter')
or (gerudo_fortress != 'normal' and gerudo_fortress != 'fast')",
# Mirror shield does not count because it cannot reflect scrub attack.
"has_shield": "(is_adult and Hylian_Shield) or (is_child and Deku_Shield)",
@ -104,11 +110,33 @@
(bridge == 'stones' and _oot_has_stones(bridge_stones)) or
(bridge == 'medallions' and _oot_has_medallions(bridge_medallions)) or
(bridge == 'dungeons' and _oot_has_dungeon_rewards(bridge_rewards)) or
(bridge == 'tokens' and (Gold_Skulltula_Token, bridge_tokens)))",
(bridge == 'tokens' and (Gold_Skulltula_Token, bridge_tokens)) or
(bridge == 'hearts' and _oot_has_hearts(bridge_hearts)))",
"can_trigger_lacs": "(
(lacs_condition == 'vanilla' and Shadow_Medallion and Spirit_Medallion) or
(lacs_condition == 'stones' and _oot_has_stones(lacs_stones)) or
(lacs_condition == 'medallions' and _oot_has_medallions(lacs_medallions)) or
(lacs_condition == 'dungeons' and _oot_has_dungeon_rewards(lacs_rewards)) or
(lacs_condition == 'tokens' and (Gold_Skulltula_Token, lacs_tokens)))"
(lacs_condition == 'tokens' and (Gold_Skulltula_Token, lacs_tokens)) or
(lacs_condition == 'hearts' and _oot_has_hearts(lacs_hearts)))",
"can_receive_ganon_bosskey": "(
(shuffle_ganon_bosskey == 'stones' and _oot_has_stones(ganon_bosskey_stones)) or
(shuffle_ganon_bosskey == 'medallions' and _oot_has_medallions(ganon_bosskey_medallions)) or
(shuffle_ganon_bosskey == 'dungeons' and _oot_has_dungeon_rewards(ganon_bosskey_rewards)) or
(shuffle_ganon_bosskey == 'tokens' and (Gold_Skulltula_Token, ganon_bosskey_tokens)) or
(shuffle_ganon_bosskey == 'hearts' and _oot_has_hearts(ganon_bosskey_hearts))) or
(shuffle_ganon_bosskey == 'triforce' and (Triforce_Piece, triforce_goal_per_world)) or
(shuffle_ganon_bosskey != 'stones' and shuffle_ganon_bosskey != 'medallions' and
shuffle_ganon_bosskey != 'dungeons' and shuffle_ganon_bosskey != 'tokens' and
shuffle_ganon_bosskey != 'hearts' and shuffle_ganon_bosskey != 'triforce')",
# Dungeon Shortcuts
"deku_tree_shortcuts": "'Deku Tree' in dungeon_shortcuts",
"dodongos_cavern_shortcuts": "'Dodongos Cavern' in dungeon_shortcuts",
"jabu_shortcuts": "'Jabu Jabus Belly' in dungeon_shortcuts",
"forest_temple_shortcuts": "'Forest Temple' in dungeon_shortcuts",
"fire_temple_shortcuts": "'Fire Temple' in dungeon_shortcuts",
"shadow_temple_shortcuts": "'Shadow Temple' in dungeon_shortcuts",
"spirit_temple_shortcuts": "'Spirit Temple' in dungeon_shortcuts",
"king_dodongo_shortcuts": "region_has_shortcuts('King Dodongo Boss Room')"
}

Binary file not shown.

View File

@ -0,0 +1,250 @@
[
# Boss and boss door logic.
# This is separated from individual dungeons because region names must match between normal/MQ
# And there are no differences in boss rooms between normal/MQ as they are separate areas.
#
# Key requirements (i.e. the only requirements for actually opening the boss door)
# belong on the door->boss connection. Any other requirements for reaching the boss door
# belong in the respective dungeon's logic json
{
"region_name": "Deku Tree Boss Door",
"scene": "Deku Tree",
"dungeon": "Deku Tree",
"exits": {
"Queen Gohma Boss Room": "True"
}
},
{
"region_name": "Queen Gohma Boss Room",
"scene": "Deku Tree Boss",
"is_boss_room": "True",
"events": {
"Deku Tree Clear": "(Nuts or can_use(Slingshot)) and can_jumpslash"
},
"locations": {
"Deku Tree Queen Gohma Heart": "'Deku Tree Clear'",
"Queen Gohma": "'Deku Tree Clear'"
},
"exits": {
"Deku Tree Boss Door": "True"
}
},
{
"region_name": "Dodongos Cavern Boss Door",
"scene": "Dodongos Cavern",
"dungeon": "Dodongos Cavern",
"exits": {
"King Dodongo Boss Room": "True"
}
},
{
"region_name": "King Dodongo Boss Room",
"scene": "Dodongos Cavern Boss",
"is_boss_room": "True",
"locations": {
"Dodongos Cavern Boss Room Chest": "True",
"Dodongos Cavern King Dodongo Heart": "
((can_use(Megaton_Hammer) and logic_dc_hammer_floor) or
has_explosives or king_dodongo_shortcuts) and
(((Bombs or Progressive_Strength_Upgrade) and can_jumpslash) or deadly_bonks == 'ohko')",
"King Dodongo": "
((can_use(Megaton_Hammer) and logic_dc_hammer_floor) or
has_explosives or king_dodongo_shortcuts) and
(((Bombs or Progressive_Strength_Upgrade) and can_jumpslash) or deadly_bonks == 'ohko')",
"Fairy Pot": "has_bottle"
},
"exits": {
"Dodongos Cavern Boss Door": "True"
}
},
{
"region_name": "Jabu Jabus Belly Boss Door",
"scene": "Jabu Jabus Belly",
"dungeon": "Jabu Jabus Belly",
"exits": {
"Barinade Boss Room": "True"
}
},
{
"region_name": "Barinade Boss Room",
"scene": "Jabu Jabus Belly Boss",
"is_boss_room": "True",
"locations": {
"Jabu Jabus Belly Barinade Heart": "can_use(Boomerang) and (Sticks or Kokiri_Sword)",
"Barinade": "can_use(Boomerang) and (Sticks or Kokiri_Sword)",
"Jabu Jabus Belly Barinade Pot 1": "True",
"Jabu Jabus Belly Barinade Pot 2": "True",
"Jabu Jabus Belly Barinade Pot 3": "True",
"Jabu Jabus Belly Barinade Pot 4": "True",
"Jabu Jabus Belly Barinade Pot 5": "True",
"Jabu Jabus Belly Barinade Pot 6": "True"
},
"exits": {
"Jabu Jabus Belly Boss Door": "False"
}
},
{
"region_name": "Forest Temple Boss Door",
"scene": "Forest Temple",
"dungeon": "Forest Temple",
"exits": {
"Phantom Ganon Boss Room": "Boss_Key_Forest_Temple"
}
},
{
"region_name": "Phantom Ganon Boss Room",
"scene": "Forest Temple Boss",
"is_boss_room": "True",
"locations": {
"Forest Temple Phantom Ganon Heart": "
can_use(Hookshot) or can_use(Bow) or (can_use(Slingshot) and Kokiri_Sword)",
"Phantom Ganon": "
can_use(Hookshot) or can_use(Bow) or (can_use(Slingshot) and Kokiri_Sword)"
},
"exits": {
"Forest Temple Boss Door": "False"
}
},
{
"region_name": "Fire Temple Boss Door",
"scene": "Fire Temple",
"dungeon": "Fire Temple",
"exits": {
"Volvagia Boss Room": "Boss_Key_Fire_Temple"
}
},
{
"region_name": "Volvagia Boss Room",
"scene": "Fire Temple Boss",
"is_boss_room": "True",
"locations": {
"Fire Temple Volvagia Heart": "can_use(Goron_Tunic) and can_use(Megaton_Hammer)",
"Volvagia": "can_use(Goron_Tunic) and can_use(Megaton_Hammer)"
},
"exits": {
"Fire Temple Boss Door": "False"
}
},
{
"region_name": "Water Temple Boss Door",
"scene": "Water Temple",
"dungeon": "Water Temple",
"exits": {
"Morpha Boss Room": "Boss_Key_Water_Temple"
}
},
{
"region_name": "Morpha Boss Room",
"scene": "Water Temple Boss",
"is_boss_room": "True",
"events": {
"Water Temple Clear": "can_use(Hookshot)"
},
"locations": {
"Morpha": "can_use(Hookshot)",
"Water Temple Morpha Heart": "can_use(Hookshot)"
},
"exits": {
"Water Temple Boss Door": "False"
}
},
{
"region_name": "Shadow Temple Boss Door",
"scene": "Shadow Temple",
"dungeon": "Shadow Temple",
"exits": {
"Bongo Bongo Boss Room": "Boss_Key_Shadow_Temple"
}
},
{
"region_name": "Bongo Bongo Boss Room",
"scene": "Shadow Temple Boss",
"is_boss_room": "True",
"locations": {
"Shadow Temple Bongo Bongo Heart": "
(Kokiri_Sword or is_adult) and
(can_use(Hookshot) or can_use(Bow) or can_use(Slingshot) or logic_shadow_bongo) and
(can_use(Lens_of_Truth) or logic_lens_bongo)",
"Bongo Bongo": "
(Kokiri_Sword or is_adult) and
(can_use(Hookshot) or can_use(Bow) or can_use(Slingshot) or logic_shadow_bongo) and
(can_use(Lens_of_Truth) or logic_lens_bongo)"
},
"exits": {
"Shadow Temple Boss Door": "False"
}
},
{
"region_name": "Spirit Temple Boss Door",
"scene": "Spirit Temple",
"dungeon": "Spirit Temple",
"exits": {
"Twinrova Boss Room": "Boss_Key_Spirit_Temple"
}
},
{
"region_name": "Twinrova Boss Room",
"scene": "Spirit Temple Boss",
"is_boss_room": "True",
"locations": {
"Spirit Temple Twinrova Heart": "can_use(Mirror_Shield)",
"Twinrova": "can_use(Mirror_Shield)"
},
"exits": {
"Spirit Temple Boss Door": "False"
}
},
{
"region_name": "Ganons Castle Tower",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Tower Boss Key Chest": "is_adult or Kokiri_Sword"
},
"exits": {
"Ganons Castle Tower Below Boss": "
(is_adult or Kokiri_Sword) and
(Boss_Key_Ganons_Castle or (shuffle_pots != 'off'))"
}
},
{
"region_name": "Ganons Castle Tower Below Boss",
"dungeon": "Ganons Castle",
"hint": "INSIDE_GANONS_CASTLE",
"alt_hint": "GANONDORFS_CHAMBER",
"locations": {
"Ganons Tower Pot 1": "True",
"Ganons Tower Pot 2": "True",
"Ganons Tower Pot 3": "True",
"Ganons Tower Pot 4": "True",
"Ganons Tower Pot 5": "True",
"Ganons Tower Pot 6": "True",
"Ganons Tower Pot 7": "True",
"Ganons Tower Pot 8": "True",
"Ganons Tower Pot 9": "True",
"Ganons Tower Pot 10": "True",
"Ganons Tower Pot 11": "True",
"Ganons Tower Pot 12": "True",
"Ganons Tower Pot 13": "True",
"Ganons Tower Pot 14": "True"
},
"exits": {
"Ganondorf Boss Room": "Boss_Key_Ganons_Castle"
}
},
{
"region_name": "Ganondorf Boss Room",
"dungeon": "Ganons Castle",
"hint": "INSIDE_GANONS_CASTLE",
"alt_hint": "GANONDORFS_CHAMBER",
"locations": {
"Ganondorf Hint": "True",
"Ganon": "can_use(Light_Arrows)"
}
}
]

View File

@ -15,13 +15,21 @@
Kokiri_Sword or (Sticks and logic_child_deadhand)",
"Bottom of the Well MQ Dead Hand Freestanding Key": "
has_explosives or (logic_botw_mq_dead_hand_key and Boomerang)",
"Bottom of the Well MQ Bombable Recovery Heart 1": "has_explosives",
"Bottom of the Well MQ Bombable Recovery Heart 2": "has_explosives",
"Bottom of the Well MQ Basement Recovery Heart 1": "True",
"Bottom of the Well MQ Basement Recovery Heart 2": "True",
"Bottom of the Well MQ Basement Recovery Heart 3": "True",
"Bottom of the Well MQ Coffin Recovery Heart 1": "
(Small_Key_Bottom_of_the_Well, 2) and (Sticks or can_use(Dins_Fire))",
"Bottom of the Well MQ Coffin Recovery Heart 2": "
(Small_Key_Bottom_of_the_Well, 2) and (Sticks or can_use(Dins_Fire))",
"Bottom of the Well MQ GS Basement": "can_child_attack",
"Bottom of the Well MQ GS Coffin Room": "
can_child_attack and (Small_Key_Bottom_of_the_Well, 2)",
(Small_Key_Bottom_of_the_Well, 2) and can_child_attack",
"Wall Fairy": "has_bottle and Slingshot" # The fairy pot is obsolete
},
"exits": {
"Bottom of the Well": "True",
"Bottom of the Well Middle": "
can_play(Zeldas_Lullaby) or (logic_botw_mq_pits and has_explosives)"
}
@ -31,14 +39,17 @@
"dungeon": "Bottom of the Well",
"locations": {
"Bottom of the Well MQ Map Chest": "True",
"Bottom of the Well MQ Lens of Truth Chest": "
has_explosives and (Small_Key_Bottom_of_the_Well, 2)",
"Bottom of the Well MQ East Inner Room Freestanding Key": "True",
"Bottom of the Well MQ Lens of Truth Chest": "
(Small_Key_Bottom_of_the_Well, 2) and has_explosives",
"Bottom of the Well MQ Center Room Right Pot 1": "True",
"Bottom of the Well MQ Center Room Right Pot 2": "True",
"Bottom of the Well MQ Center Room Right Pot 3": "True",
"Bottom of the Well MQ East Inner Room Pot 1": "True",
"Bottom of the Well MQ East Inner Room Pot 2": "True",
"Bottom of the Well MQ East Inner Room Pot 3": "True",
"Bottom of the Well MQ GS West Inner Room": "
can_child_attack and (logic_botw_mq_pits or has_explosives)"
},
"exits": {
"Bottom of the Well Perimeter": "True"
}
}
]

View File

@ -11,43 +11,81 @@
"region_name": "Bottom of the Well Main Area",
"dungeon": "Bottom of the Well",
"locations": {
"Bottom of the Well Front Left Fake Wall Chest": "logic_lens_botw or can_use(Lens_of_Truth)",
"Bottom of the Well Front Center Bombable Chest": "has_explosives",
"Bottom of the Well Right Bottom Fake Wall Chest": "logic_lens_botw or can_use(Lens_of_Truth)",
"Bottom of the Well Compass Chest": "logic_lens_botw or can_use(Lens_of_Truth)",
"Bottom of the Well Center Skulltula Chest": "logic_lens_botw or can_use(Lens_of_Truth)",
"Bottom of the Well Back Left Bombable Chest": "has_explosives and (logic_lens_botw or can_use(Lens_of_Truth))",
"Bottom of the Well Freestanding Key": "Sticks or can_use(Dins_Fire)",
"Bottom of the Well Lens of Truth Chest": "
can_play(Zeldas_Lullaby) and
(Kokiri_Sword or (Sticks and logic_child_deadhand))",
#Sword not strictly necessary but frankly being forced to do this with sticks isn't fair
"Bottom of the Well Invisible Chest": "can_play(Zeldas_Lullaby) and (logic_lens_botw or can_use(Lens_of_Truth))",
"Bottom of the Well Underwater Front Chest": "can_play(Zeldas_Lullaby)",
"Bottom of the Well Underwater Left Chest": "can_play(Zeldas_Lullaby)",
"Bottom of the Well Underwater Front Chest": "can_play(Zeldas_Lullaby)",
"Bottom of the Well Map Chest": "
has_explosives or
((((Small_Key_Bottom_of_the_Well, 3) and (logic_lens_botw or can_use(Lens_of_Truth))) or
can_use(Dins_Fire) or (logic_botw_basement and Sticks)) and
Progressive_Strength_Upgrade)",
"Bottom of the Well Fire Keese Chest": "
(Small_Key_Bottom_of_the_Well, 3) and (logic_lens_botw or can_use(Lens_of_Truth))", #These pits are really unfair.
"Bottom of the Well Like Like Chest": "
(Small_Key_Bottom_of_the_Well, 3) and (logic_lens_botw or can_use(Lens_of_Truth))",
"Bottom of the Well GS West Inner Room": "
Boomerang and (logic_lens_botw or can_use(Lens_of_Truth)) and
(Small_Key_Bottom_of_the_Well, 3)",
"Bottom of the Well GS East Inner Room": "
Boomerang and (logic_lens_botw or can_use(Lens_of_Truth)) and
(Small_Key_Bottom_of_the_Well, 3)",
"Bottom of the Well GS Like Like Cage": "
Boomerang and (logic_lens_botw or can_use(Lens_of_Truth)) and
(Small_Key_Bottom_of_the_Well, 3)",
(Progressive_Strength_Upgrade and
(at('Bottom of the Well Behind Locked Doors', True) or
can_use(Dins_Fire) or (logic_botw_basement and Sticks)))",
"Bottom of the Well Invisible Chest": "
can_play(Zeldas_Lullaby) and (logic_lens_botw or can_use(Lens_of_Truth))",
# Sword not strictly necessary but being forced to do this with sticks isn't fair
"Bottom of the Well Lens of Truth Chest": "
can_play(Zeldas_Lullaby) and (Kokiri_Sword or (Sticks and logic_child_deadhand))",
"Bottom of the Well Coffin Recovery Heart 1": "Sticks or can_use(Dins_Fire)",
"Bottom of the Well Coffin Recovery Heart 2": "True",
"Bottom of the Well Near Entrance Pot 1": "True",
"Bottom of the Well Near Entrance Pot 2": "True",
"Bottom of the Well Underwater Pot": "
can_play(Zeldas_Lullaby) or can_use(Slingshot) or can_use(Boomerang) or has_bombchus",
"Bottom of the Well Basement Pot 1": "True",
"Bottom of the Well Basement Pot 2": "True",
"Bottom of the Well Basement Pot 3": "True",
"Bottom of the Well Basement Pot 4": "True",
"Bottom of the Well Basement Pot 5": "True",
"Bottom of the Well Basement Pot 6": "True",
"Bottom of the Well Basement Pot 7": "True",
"Bottom of the Well Basement Pot 8": "True",
"Bottom of the Well Basement Pot 9": "True",
"Bottom of the Well Basement Pot 10": "True",
"Bottom of the Well Basement Pot 11": "True",
"Bottom of the Well Basement Pot 12": "True",
"Bottom of the Well Left Side Pot 1": "True",
"Bottom of the Well Left Side Pot 2": "True",
"Bottom of the Well Left Side Pot 3": "True",
"Stick Pot": "True",
"Nut Pot": "True"
},
"exits": {
"Bottom of the Well" : "True"
"Bottom of the Well Behind Fake Walls": "logic_lens_botw or can_use(Lens_of_Truth)"
}
},
{
"region_name": "Bottom of the Well Behind Fake Walls",
"dungeon": "Bottom of the Well",
"locations": {
"Bottom of the Well Front Left Fake Wall Chest": "True",
"Bottom of the Well Right Bottom Fake Wall Chest": "True",
"Bottom of the Well Compass Chest": "True",
"Bottom of the Well Center Skulltula Chest": "True",
"Bottom of the Well Back Left Bombable Chest": "has_explosives",
"Bottom of the Well Center Room Pit Fall Blue Rupee 1": "True",
"Bottom of the Well Center Room Pit Fall Blue Rupee 2": "True",
"Bottom of the Well Center Room Pit Fall Blue Rupee 3": "True",
"Bottom of the Well Center Room Pit Fall Blue Rupee 4": "True",
"Bottom of the Well Center Room Pit Fall Blue Rupee 5": "True"
},
"exits": {
"Bottom of the Well Behind Locked Doors": "(Small_Key_Bottom_of_the_Well, 3)"
}
},
{
"region_name": "Bottom of the Well Behind Locked Doors",
"dungeon": "Bottom of the Well",
"locations": {
# Lens required because these pits are really unfair.
"Bottom of the Well Fire Keese Chest": "True",
"Bottom of the Well Like Like Chest": "True",
"Bottom of the Well West Inner Room Flying Pot 1": "True",
"Bottom of the Well West Inner Room Flying Pot 2": "True",
"Bottom of the Well West Inner Room Flying Pot 3": "True",
"Bottom of the Well Fire Keese Pot": "True",
"Bottom of the Well GS West Inner Room": "Boomerang",
"Bottom of the Well GS East Inner Room": "Boomerang",
"Bottom of the Well GS Like Like Cage": "Boomerang"
}
}
]

View File

@ -7,7 +7,14 @@
"Deku Tree MQ Slingshot Chest": "is_adult or can_child_attack",
"Deku Tree MQ Slingshot Room Back Chest": "has_fire_source_with_torch or can_use(Bow)",
"Deku Tree MQ Basement Chest": "has_fire_source_with_torch or can_use(Bow)",
"Deku Tree MQ GS Lobby": "is_adult or can_child_attack",
"Deku Tree MQ Lower Lobby Recovery Heart": "True",
"Deku Tree MQ Slingshot Room Recovery Heart": "True",
"Deku Tree MQ Lobby Crate": "can_break_crate",
"Deku Tree MQ Slingshot Room Crate 1": "can_break_crate",
"Deku Tree MQ Slingshot Room Crate 2": "can_break_crate",
"Deku Tree MQ GS Lobby": "
is_adult or Sticks or Kokiri_Sword or has_explosives or can_use(Dins_Fire) or
((Slingshot or Boomerang) and can_break_crate)",
"Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang",
"Deku Baba Nuts": "
is_adult or Slingshot or Sticks or
@ -15,12 +22,20 @@
},
"exits": {
"KF Outside Deku Tree": "True",
"Deku Tree Compass Room": "
here(can_use(Slingshot) or can_use(Bow)) and
here(has_fire_source_with_torch or can_use(Bow))",
"Deku Tree Near Compass Room": "here(has_fire_source_with_torch or can_use(Bow))",
"Deku Tree Basement Water Room Front": "
here(can_use(Slingshot) or can_use(Bow)) and here(has_fire_source_with_torch)",
"Deku Tree Basement Ledge": "logic_deku_b1_skip or here(is_adult)"
"Deku Tree Basement Ledge": "deku_tree_shortcuts or here(is_adult) or logic_deku_b1_skip"
}
},
{
"region_name": "Deku Tree Near Compass Room",
"dungeon": "Deku Tree",
"locations": {
"Deku Tree MQ Near Compass Room Recovery Heart": "True"
},
"exits": {
"Deku Tree Compass Room": "here(can_use(Slingshot) or can_use(Bow))"
}
},
{
@ -28,14 +43,13 @@
"dungeon": "Deku Tree",
"locations": {
"Deku Tree MQ Compass Chest": "True",
"Deku Tree MQ Compass Room Recovery Heart": "
has_bombchus or (Bombs and (can_play(Song_of_Time) or is_adult)) or
(can_use(Megaton_Hammer) and (can_play(Song_of_Time) or logic_deku_mq_compass_gs))",
"Deku Tree MQ GS Compass Room": "
(can_use(Hookshot) or can_use(Boomerang)) and
here(has_bombchus or
(Bombs and (can_play(Song_of_Time) or is_adult)) or
here(has_bombchus or (Bombs and (can_play(Song_of_Time) or is_adult)) or
(can_use(Megaton_Hammer) and (can_play(Song_of_Time) or logic_deku_mq_compass_gs)))"
},
"exits": {
"Deku Tree Lobby": "True"
}
},
{
@ -47,8 +61,7 @@
"exits": {
"Deku Tree Basement Water Room Back": "
logic_deku_mq_log or (is_child and (Deku_Shield or Hylian_Shield)) or
can_use(Longshot) or (can_use(Hookshot) and can_use(Iron_Boots))",
"Deku Tree Lobby": "True"
can_use(Longshot) or (can_use(Hookshot) and can_use(Iron_Boots))"
}
},
{
@ -86,22 +99,23 @@
"region_name": "Deku Tree Basement Ledge",
"dungeon": "Deku Tree",
"locations": {
"Deku Tree MQ Deku Scrub": "can_stun_deku",
"Deku Tree Queen Gohma Heart": "
here(has_fire_source_with_torch) and here(has_shield) and
(is_adult or Kokiri_Sword or Sticks)",
"Queen Gohma": "
here(has_fire_source_with_torch) and here(has_shield) and
(is_adult or Kokiri_Sword or Sticks)"
},
"events": {
"Deku Tree Clear": "
here(has_fire_source_with_torch) and here(has_shield) and
(is_adult or Kokiri_Sword or Sticks)"
"Deku Tree MQ Deku Scrub": "can_stun_deku"
},
"exits": {
"Deku Tree Basement Back Room": "is_child",
"Deku Tree Lobby": "True"
"Deku Tree Before Boss": "deku_tree_shortcuts or here(has_fire_source_with_torch)"
}
},
{
"region_name": "Deku Tree Before Boss",
"dungeon": "Deku Tree",
"locations": {
"Deku Tree MQ Basement Recovery Heart 1": "True",
"Deku Tree MQ Basement Recovery Heart 2": "True",
"Deku Tree MQ Basement Recovery Heart 3": "True"
},
"exits": {
"Deku Tree Boss Door": "deku_tree_shortcuts or here(has_shield)"
}
}
]

View File

@ -6,12 +6,9 @@
"Deku Tree Map Chest": "True",
"Deku Tree Compass Chest": "True",
"Deku Tree Compass Room Side Chest": "True",
"Deku Tree Basement Chest": "is_adult or can_child_attack or Nuts",
"Deku Tree Lower Lobby Recovery Heart": "True",
"Deku Tree Upper Lobby Recovery Heart": "is_adult or can_child_attack or Nuts",
"Deku Tree GS Compass Room": "is_adult or can_child_attack",
"Deku Tree GS Basement Vines": "
can_use_projectile or can_use(Dins_Fire) or
(logic_deku_basement_gs and (is_adult or Sticks or Kokiri_Sword))",
"Deku Tree GS Basement Gate": "is_adult or can_child_attack",
"Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang",
"Deku Baba Nuts": "
is_adult or Slingshot or Sticks or
@ -20,14 +17,7 @@
"exits": {
"KF Outside Deku Tree": "True",
"Deku Tree Slingshot Room": "here(has_shield)",
"Deku Tree Basement Backroom": "
(here(has_fire_source_with_torch or can_use(Bow)) and
here(can_use(Slingshot) or can_use(Bow))) or
(is_child and (logic_deku_b1_skip or here(is_adult)))",
"Deku Tree Boss Room": "
here(has_fire_source_with_torch or
(logic_deku_b1_webs_with_bow and can_use(Bow))) and
(logic_deku_b1_skip or here(is_adult or can_use(Slingshot)))"
"Deku Tree Basement": "deku_tree_shortcuts or is_adult or can_child_attack or Nuts"
}
},
{
@ -36,13 +26,27 @@
"locations": {
"Deku Tree Slingshot Chest": "True",
"Deku Tree Slingshot Room Side Chest": "True"
},
"exits": {
"Deku Tree Lobby": "True"
}
},
{
"region_name": "Deku Tree Basement Backroom",
"region_name": "Deku Tree Basement",
"dungeon": "Deku Tree",
"locations": {
"Deku Tree Basement Chest": "True",
"Deku Tree GS Basement Gate": "is_adult or can_child_attack",
"Deku Tree GS Basement Vines": "
can_use_projectile or can_use(Dins_Fire) or
(logic_deku_basement_gs and (is_adult or Sticks or Kokiri_Sword))"
},
"exits": {
"Deku Tree Basement Back Room": "
here(has_fire_source_with_torch or can_use(Bow)) and
here(can_use(Slingshot) or can_use(Bow))",
"Deku Tree Basement Ledge": "deku_tree_shortcuts or here(is_adult) or logic_deku_b1_skip"
}
},
{
"region_name": "Deku Tree Basement Back Room",
"dungeon": "Deku Tree",
"locations": {
"Deku Tree GS Basement Back Room": "
@ -51,24 +55,29 @@
(can_use(Boomerang) or can_use(Hookshot))"
},
"exits": {
"Deku Tree Lobby": "True"
"Deku Tree Basement Ledge": "is_child"
}
},
{
"region_name": "Deku Tree Boss Room",
"region_name": "Deku Tree Basement Ledge",
"dungeon": "Deku Tree",
"events": {
"Deku Tree Clear": "
here(has_shield) and (is_adult or Kokiri_Sword or Sticks)"
"exits": {
"Deku Tree Basement Back Room": "is_child",
"Deku Tree Before Boss": "
deku_tree_shortcuts or
here(has_fire_source_with_torch or (logic_deku_b1_webs_with_bow and can_use(Bow)))"
}
},
{
"region_name": "Deku Tree Before Boss",
"dungeon": "Deku Tree",
"locations": {
"Deku Tree Queen Gohma Heart": "
here(has_shield) and (is_adult or Kokiri_Sword or Sticks)",
"Queen Gohma": "
here(has_shield) and (is_adult or Kokiri_Sword or Sticks)"
"Deku Tree Basement Recovery Heart 1": "True",
"Deku Tree Basement Recovery Heart 2": "True",
"Deku Tree Basement Recovery Heart 3": "True"
},
"exits": {
"Deku Tree Lobby": "True"
"Deku Tree Boss Door": "deku_tree_shortcuts or here(has_shield)"
}
}
]

View File

@ -5,86 +5,219 @@
"exits": {
"Death Mountain": "True",
"Dodongos Cavern Lobby": "
here(can_blast_or_smash or Progressive_Strength_Upgrade)"
here(can_blast_or_smash or Progressive_Strength_Upgrade) or
dodongos_cavern_shortcuts"
}
},
{
"region_name": "Dodongos Cavern Lobby",
"dungeon": "Dodongos Cavern",
"locations": {
"Deku Baba Sticks": "is_adult or Kokiri_Sword or can_use(Boomerang)",
"Dodongos Cavern MQ Map Chest": "True",
"Dodongos Cavern MQ Compass Chest": "is_adult or can_child_attack or Nuts",
"Dodongos Cavern MQ Larvae Room Chest": "can_use(Sticks) or has_fire_source",
"Dodongos Cavern MQ Torch Puzzle Room Chest": "
can_blast_or_smash or can_use(Sticks) or can_use(Dins_Fire) or
(is_adult and (logic_dc_jump or Hover_Boots or Progressive_Hookshot))",
"Dodongos Cavern MQ GS Song of Time Block Room": "
can_play(Song_of_Time) and (can_child_attack or is_adult)",
"Dodongos Cavern MQ GS Larvae Room": "can_use(Sticks) or has_fire_source",
"Dodongos Cavern MQ GS Lizalfos Room": "can_blast_or_smash",
"Dodongos Cavern MQ Map Chest": "can_blast_or_smash or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Deku Scrub Lobby Rear": "can_stun_deku",
"Dodongos Cavern MQ Deku Scrub Lobby Front": "can_stun_deku",
"Dodongos Cavern MQ Deku Scrub Staircase": "can_stun_deku",
"Dodongos Cavern Gossip Stone": "True",
"Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle"
"Dodongos Cavern Gossip Stone": "here(can_blast_or_smash or Progressive_Strength_Upgrade)",
"Gossip Stone Fairy": "
(can_blast_or_smash or Progressive_Strength_Upgrade) and
can_summon_gossip_fairy and has_bottle"
},
"exits": {
"Dodongos Cavern Lower Right Side": "
here(can_blast_or_smash or
((can_use(Sticks) or can_use(Dins_Fire)) and can_take_damage))",
"Dodongos Cavern Bomb Bag Area": "
is_adult or (here(is_adult) and has_explosives) or
(logic_dc_mq_child_bombs and (Kokiri_Sword or Sticks) and can_take_damage)",
"Dodongos Cavern Boss Area": "
has_explosives or
(logic_dc_mq_eyes and Progressive_Strength_Upgrade and
(is_adult or logic_dc_mq_child_back) and
(here(can_use(Sticks)) or can_use(Dins_Fire) or
(is_adult and (logic_dc_jump or Megaton_Hammer or Hover_Boots or Hookshot))))"
"Dodongos Cavern Elevator": "here(can_blast_or_smash or Progressive_Strength_Upgrade)",
"Dodongos Cavern Lower Right Side": "here(can_blast_or_smash)",
"Dodongos Cavern Poes Room": "is_adult",
"Dodongos Cavern Mouth": "dodongos_cavern_shortcuts"
}
},
{
"region_name": "Dodongos Cavern Elevator",
"dungeon": "Dodongos Cavern",
"locations": {
# Regardless of how you destroy the boulder on the elevator switch,
# you will always be able to access the upper staircase in some way.
"Dodongos Cavern MQ Deku Scrub Staircase": "can_stun_deku",
"Dodongos Cavern MQ Staircase Pot 1": "True",
"Dodongos Cavern MQ Staircase Pot 2": "True",
"Dodongos Cavern MQ Staircase Pot 3": "True",
"Dodongos Cavern MQ Staircase Pot 4": "True",
"Dodongos Cavern MQ Staircase Crate Bottom Left": "True",
"Dodongos Cavern MQ Staircase Crate Bottom Right": "True",
"Dodongos Cavern MQ Staircase Crate Mid Left": "can_break_crate",
"Dodongos Cavern MQ Staircase Crate Mid Right": "can_break_crate",
"Dodongos Cavern MQ Staircase Crate Top Left": "can_break_crate",
"Dodongos Cavern MQ Staircase Crate Top Right": "can_break_crate",
"Dodongos Cavern MQ GS Song of Time Block Room": "
can_play(Song_of_Time) and (can_child_attack or is_adult)",
"Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang"
},
"exits": {
"Dodongos Cavern Torch Puzzle Lower": "
(deadly_bonks != 'ohko' or can_use(Nayrus_Love) or can_blast_or_smash) and
(is_adult or can_child_attack or Nuts)",
"Dodongos Cavern Torch Puzzle Upper": "
here(can_blast_or_smash or can_use(Dins_Fire)) or
at('Dodongos Cavern Torch Puzzle Upper', Progressive_Strength_Upgrade)",
"Dodongos Cavern Poes Room": "
logic_dc_mq_child_bombs and (Kokiri_Sword or Sticks) and can_take_damage",
"Dodongos Cavern Mouth": "has_explosives"
}
},
{
"region_name": "Dodongos Cavern Torch Puzzle Lower",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Compass Chest": "True",
"Dodongos Cavern MQ Torch Puzzle Room Recovery Heart": "True",
"Dodongos Cavern MQ Torch Puzzle Room Pot Pillar": "
can_use(Boomerang) or at('Dodongos Cavern Torch Puzzle Upper', True)"
},
"exits": {
"Dodongos Cavern Larvae Room": "has_fire_source_with_torch",
"Dodongos Cavern Before Upper Lizalfos": "has_fire_source_with_torch",
"Dodongos Cavern Torch Puzzle Upper": "
is_adult and (logic_dc_jump or Hover_Boots or Hookshot)"
}
},
{
"region_name": "Dodongos Cavern Larvae Room",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Larvae Room Chest": "True",
"Dodongos Cavern MQ Larvae Room Crate 1": "can_break_crate",
"Dodongos Cavern MQ Larvae Room Crate 2": "can_break_crate",
"Dodongos Cavern MQ Larvae Room Crate 3": "can_break_crate",
"Dodongos Cavern MQ Larvae Room Crate 4": "can_break_crate",
"Dodongos Cavern MQ Larvae Room Crate 5": "can_break_crate",
"Dodongos Cavern MQ Larvae Room Crate 6": "can_break_crate",
"Dodongos Cavern MQ GS Larvae Room": "True"
}
},
{
"region_name": "Dodongos Cavern Before Upper Lizalfos",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Before Upper Lizalfos Pot 1": "True",
"Dodongos Cavern MQ Before Upper Lizalfos Pot 2": "True"
},
"exits": {
"Dodongos Cavern Torch Puzzle Upper": "can_use(Sticks)"
}
},
{
"region_name": "Dodongos Cavern Torch Puzzle Upper",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Torch Puzzle Room Chest": "True",
"Dodongos Cavern MQ Upper Lizalfos Pot 1": "True",
"Dodongos Cavern MQ Upper Lizalfos Pot 2": "True",
"Dodongos Cavern MQ Upper Lizalfos Pot 3": "True",
"Dodongos Cavern MQ Upper Lizalfos Pot 4": "True",
"Dodongos Cavern MQ After Upper Lizalfos Pot 1": "True",
"Dodongos Cavern MQ After Upper Lizalfos Pot 2": "True",
"Dodongos Cavern MQ Torch Puzzle Room Pot Corner": "True",
"Dodongos Cavern MQ After Upper Lizalfos Crate 1": "True",
"Dodongos Cavern MQ After Upper Lizalfos Crate 2": "True",
"Dodongos Cavern MQ GS Lizalfos Room": "can_blast_or_smash"
},
"exits": {
"Dodongos Cavern Torch Puzzle Lower": "True",
"Dodongos Cavern Before Upper Lizalfos": "is_adult or Slingshot or Bombs or Kokiri_Sword",
"Dodongos Cavern Lower Right Side": "Progressive_Strength_Upgrade and can_take_damage",
"Dodongos Cavern Lower Lizalfos": "has_explosives",
"Dodongos Cavern Mouth": "
Progressive_Strength_Upgrade and
here((logic_dc_mq_eyes_adult and is_adult) or (logic_dc_mq_eyes_child and is_child))"
}
},
{
"region_name": "Dodongos Cavern Lower Right Side",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos": "can_stun_deku"
"Dodongos Cavern MQ Deku Scrub Side Room Near Lower Lizalfos": "
(can_blast_or_smash or Progressive_Strength_Upgrade) and can_stun_deku",
"Dodongos Cavern MQ Right Side Pot 1": "True",
"Dodongos Cavern MQ Right Side Pot 2": "True",
"Dodongos Cavern MQ Right Side Pot 3": "True",
"Dodongos Cavern MQ Right Side Pot 4": "True"
},
"exits": {
"Dodongos Cavern Bomb Bag Area": "
"Dodongos Cavern Poes Room": "
(here(can_use(Bow)) or Progressive_Strength_Upgrade or
can_use(Dins_Fire) or has_explosives) and
can_use(Slingshot)"
}
},
{
"region_name": "Dodongos Cavern Bomb Bag Area",
"region_name": "Dodongos Cavern Lower Lizalfos",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Lower Lizalfos Hidden Recovery Heart": "True"
},
"exits": {
# Child can fall down from above to reach Poes room, but Adult must defeat the
# lower Lizalfos here first, since they don't spawn when jumping down from above.
"Dodongos Cavern Poes Room": "here(is_adult)"
}
},
{
"region_name": "Dodongos Cavern Poes Room",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Bomb Bag Chest": "True",
"Dodongos Cavern MQ Poes Room Pot 1": "True",
"Dodongos Cavern MQ Poes Room Pot 2": "True",
"Dodongos Cavern MQ Poes Room Pot 3": "True",
"Dodongos Cavern MQ Poes Room Pot 4": "True",
"Dodongos Cavern MQ Poes Room Crate 1": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate 2": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate 3": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate 4": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate 5": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate 6": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate 7": "can_break_crate or Progressive_Strength_Upgrade",
"Dodongos Cavern MQ Poes Room Crate Near Bomb Flower": "
can_break_crate or Progressive_Strength_Upgrade or can_use(Bow) or can_use(Dins_Fire)",
"Dodongos Cavern MQ GS Scrub Room": "
(here(can_use(Bow)) or Progressive_Strength_Upgrade or
can_use(Dins_Fire) or has_explosives) and
(can_use(Hookshot) or can_use(Boomerang))"
},
"exits": {
"Dodongos Cavern Lower Right Side": "True"
"Dodongos Cavern Lower Right Side": "True",
"Dodongos Cavern Lower Lizalfos": "True"
}
},
{
"region_name": "Dodongos Cavern Boss Area",
"region_name": "Dodongos Cavern Mouth",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Under Grave Chest": "True",
"Dodongos Cavern Boss Room Chest": "True",
"Dodongos Cavern King Dodongo Heart": "
can_blast_or_smash and (Bombs or Progressive_Strength_Upgrade) and
(is_adult or Sticks or Kokiri_Sword)",
"King Dodongo": "
can_blast_or_smash and (Bombs or Progressive_Strength_Upgrade) and
(is_adult or Sticks or Kokiri_Sword)",
"Dodongos Cavern MQ GS Back Area": "True",
"Dodongos Cavern MQ Room Before Boss Pot 1": "True",
"Dodongos Cavern MQ Room Before Boss Pot 2": "True",
"Dodongos Cavern MQ Armos Army Room Pot 1": "True",
"Dodongos Cavern MQ Armos Army Room Pot 2": "True",
"Dodongos Cavern MQ Back Poe Room Pot 1": "True",
"Dodongos Cavern MQ Back Poe Room Pot 2": "True",
"Dodongos Cavern MQ GS Back Area": "
can_use(Boomerang) or
at('Dodongos Cavern Before Boss', is_adult or can_child_attack or
Progressive_Strength_Upgrade)"
},
"exits": {
# The final line of this exit is for using an Armos to explode the bomb flowers.
"Dodongos Cavern Before Boss": "
is_adult or has_explosives or can_use(Dins_Fire) or dodongos_cavern_shortcuts or
Sticks or ((Nuts or Boomerang) and (Kokiri_Sword or Slingshot))"
}
},
{
"region_name": "Dodongos Cavern Before Boss",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern MQ Armos Army Room Upper Pot": "True",
"Fairy Pot": "has_bottle"
},
"exits": {
"Dodongos Cavern Boss Door": "True"
}
}
]

View File

@ -5,47 +5,79 @@
"exits": {
"Death Mountain": "True",
"Dodongos Cavern Lobby": "
here(can_blast_or_smash or Progressive_Strength_Upgrade)"
here(can_blast_or_smash or Progressive_Strength_Upgrade) or
dodongos_cavern_shortcuts"
}
},
{
"region_name": "Dodongos Cavern Lobby",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Map Chest": "True",
"Dodongos Cavern GS Side Room Near Lower Lizalfos": "
has_explosives or is_adult or Slingshot or
Boomerang or Sticks or Kokiri_Sword",
"Dodongos Cavern GS Scarecrow": "
can_use(Scarecrow) or can_use(Longshot) or
(logic_dc_scarecrow_gs and (is_adult or can_child_attack))",
"Dodongos Cavern Deku Scrub Side Room Near Dodongos": "
is_adult or Slingshot or Sticks or
has_explosives or Kokiri_Sword",
"Dodongos Cavern Deku Scrub Lobby": "True",
"Dodongos Cavern Gossip Stone": "True",
"Gossip Stone Fairy": "can_summon_gossip_fairy and has_bottle"
"Dodongos Cavern Map Chest": "can_blast_or_smash or Progressive_Strength_Upgrade",
"Dodongos Cavern Deku Scrub Lobby": "can_stun_deku or Progressive_Strength_Upgrade",
"Dodongos Cavern Gossip Stone": "here(can_blast_or_smash or Progressive_Strength_Upgrade)",
"Gossip Stone Fairy": "
(can_blast_or_smash or Progressive_Strength_Upgrade) and
can_summon_gossip_fairy and has_bottle"
},
"exits": {
"Dodongos Cavern Beginning": "True",
"Dodongos Cavern Lower Right Side": "has_explosives or Progressive_Strength_Upgrade",
"Dodongos Cavern Torch Room": "is_adult",
"Dodongos Cavern Staircase Room": "
here(is_adult or Sticks or
(can_use(Dins_Fire) and (Slingshot or has_explosives or Kokiri_Sword)))",
"Dodongos Cavern Far Bridge": "at('Dodongos Cavern Far Bridge', True)"
at('Dodongos Cavern Torch Room', is_adult or Sticks or can_use(Dins_Fire))",
"Dodongos Cavern Far Bridge": "at('Dodongos Cavern Far Bridge', True)",
"Dodongos Cavern Before Boss": "dodongos_cavern_shortcuts"
}
},
{
"region_name": "Dodongos Cavern Lower Right Side",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Lower Lizalfos Hidden Recovery Heart": "True",
"Dodongos Cavern Right Side Pot 1": "True",
"Dodongos Cavern Right Side Pot 2": "True",
"Dodongos Cavern Right Side Pot 3": "True",
"Dodongos Cavern Right Side Pot 4": "True",
"Dodongos Cavern Right Side Pot 5": "True",
"Dodongos Cavern Right Side Pot 6": "True",
"Dodongos Cavern Lower Lizalfos Pot 1": "True",
"Dodongos Cavern Lower Lizalfos Pot 2": "True",
"Dodongos Cavern Lower Lizalfos Pot 3": "True",
"Dodongos Cavern Lower Lizalfos Pot 4": "True",
"Dodongos Cavern GS Side Room Near Lower Lizalfos": "
is_adult or has_explosives or Sticks or Slingshot or Boomerang or Kokiri_Sword",
"Dodongos Cavern GS Scarecrow": "
can_use(Scarecrow) or can_use(Longshot) or
(logic_dc_scarecrow_gs and (is_adult or can_child_attack))"
},
"exits": {
"Dodongos Cavern Torch Room": "Sticks or Slingshot or Bombs or Kokiri_Sword"
}
},
{
"region_name": "Dodongos Cavern Torch Room",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Deku Scrub Side Room Near Dodongos": "
can_blast_or_smash or Progressive_Strength_Upgrade",
"Dodongos Cavern Torch Room Pot 1": "True",
"Dodongos Cavern Torch Room Pot 2": "True",
"Dodongos Cavern Torch Room Pot 3": "True",
"Dodongos Cavern Torch Room Pot 4": "True"
},
"exits": {
"Dodongos Cavern Lower Right Side": "True"
}
},
{
"region_name": "Dodongos Cavern Staircase Room",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Compass Chest": "True",
"Dodongos Cavern Compass Chest": "can_blast_or_smash or Progressive_Strength_Upgrade",
"Dodongos Cavern GS Vines Above Stairs": "
has_explosives or Progressive_Strength_Upgrade or can_use(Dins_Fire) or
(logic_dc_staircase and can_use(Bow)) or
(logic_dc_vines_gs and can_use(Longshot))"
at('Dodongos Cavern Climb', True) or (logic_dc_vines_gs and can_use(Longshot))"
},
"exits": {
"Dodongos Cavern Lobby": "True",
"Dodongos Cavern Climb": "
has_explosives or Progressive_Strength_Upgrade or
can_use(Dins_Fire) or (logic_dc_staircase and can_use(Bow))"
@ -61,14 +93,46 @@
(logic_dc_scrub_room and is_adult and Progressive_Strength_Upgrade)",
"Dodongos Cavern Deku Scrub Near Bomb Bag Left": "
can_blast_or_smash or
(logic_dc_scrub_room and is_adult and Progressive_Strength_Upgrade)"
(logic_dc_scrub_room and is_adult and Progressive_Strength_Upgrade)",
"Dodongos Cavern Blade Room Behind Block Recovery Heart": "True",
"Dodongos Cavern Staircase Pot 1": "True",
"Dodongos Cavern Staircase Pot 2": "True",
"Dodongos Cavern Staircase Pot 3": "True",
"Dodongos Cavern Staircase Pot 4": "True",
"Dodongos Cavern Blade Room Pot 1": "
can_use(Boomerang) or at('Dodongos Cavern Far Bridge', True)",
"Dodongos Cavern Blade Room Pot 2": "
can_use(Boomerang) or at('Dodongos Cavern Far Bridge', True)"
},
"exits": {
"Dodongos Cavern Lobby": "True",
"Dodongos Cavern Before Upper Lizalfos": "
here(can_blast_or_smash or Progressive_Strength_Upgrade)",
"Dodongos Cavern Far Bridge": "
(is_child and (Slingshot or
(logic_dc_slingshot_skip and (Sticks or has_explosives or Kokiri_Sword)))) or
(is_adult and (Bow or Hover_Boots or can_use(Longshot) or logic_dc_jump))"
is_adult and (logic_dc_jump or Hover_Boots or Longshot)"
}
},
{
"region_name": "Dodongos Cavern Before Upper Lizalfos",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Single Eye Switch Room Pot 1": "True",
"Dodongos Cavern Single Eye Switch Room Pot 2": "True"
},
"exits": {
"Dodongos Cavern Upper Lizalfos": "
(is_child and (Slingshot or logic_dc_slingshot_skip)) or can_use(Bow)"
}
},
{
"region_name": "Dodongos Cavern Upper Lizalfos",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Lizalfos Upper Recovery Heart 1": "True",
"Dodongos Cavern Lizalfos Upper Recovery Heart 2": "True"
},
"exits": {
"Dodongos Cavern Before Upper Lizalfos": "True",
"Dodongos Cavern Far Bridge": "is_adult or Sticks or Slingshot or Bombs or Kokiri_Sword"
}
},
{
@ -77,29 +141,27 @@
"locations": {
"Dodongos Cavern Bomb Bag Chest": "True",
"Dodongos Cavern End of Bridge Chest": "can_blast_or_smash",
"Dodongos Cavern Double Eye Switch Room Pot 1": "True",
"Dodongos Cavern Double Eye Switch Room Pot 2": "True",
"Dodongos Cavern GS Alcove Above Stairs": "can_use(Hookshot) or can_use(Boomerang)"
},
"exits": {
"Dodongos Cavern Boss Area": "has_explosives",
"Dodongos Cavern Lobby": "True"
"Dodongos Cavern Before Boss": "has_explosives",
"Dodongos Cavern Upper Lizalfos": "True"
}
},
{
"region_name": "Dodongos Cavern Boss Area",
"region_name": "Dodongos Cavern Before Boss",
"dungeon": "Dodongos Cavern",
"locations": {
"Dodongos Cavern Boss Room Chest": "True",
"Dodongos Cavern King Dodongo Heart": "
(Bombs or Progressive_Strength_Upgrade) and
(is_adult or Sticks or Kokiri_Sword)",
"King Dodongo": "
(Bombs or Progressive_Strength_Upgrade) and
(is_adult or Sticks or Kokiri_Sword)",
"Dodongos Cavern GS Back Room": "True",
"Dodongos Cavern Last Block Pot 1": "True",
"Dodongos Cavern Last Block Pot 2": "True",
"Dodongos Cavern Last Block Pot 3": "True",
"Dodongos Cavern GS Back Room": "can_blast_or_smash",
"Fairy Pot": "has_bottle"
},
"exits": {
"Dodongos Cavern Lobby": "True"
"Dodongos Cavern Boss Door": "True"
}
}
]

View File

@ -5,110 +5,221 @@
"locations": {
"Fire Temple MQ Map Room Side Chest": "
is_adult or Kokiri_Sword or Sticks or Slingshot or Bombs or can_use(Dins_Fire)",
"Fire Temple MQ Near Boss Chest": "
(logic_fewer_tunic_requirements or can_use(Goron_Tunic)) and
(((can_use(Hover_Boots) or (logic_fire_mq_near_boss and can_use(Bow))) and has_fire_source) or
(can_use(Hookshot) and (can_use(Fire_Arrows) or
(can_use(Dins_Fire) and
((damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or
can_use(Goron_Tunic) or can_use(Bow) or can_use(Longshot))))))"
"Fire Temple MQ First Room Pot 1": "True",
"Fire Temple MQ First Room Pot 2": "True"
},
"exits": {
"DMC Fire Temple Entrance": "True",
"Fire Boss Room": "
can_use(Goron_Tunic) and can_use(Megaton_Hammer) and Boss_Key_Fire_Temple and
((has_fire_source and (logic_fire_boss_door_jump or Hover_Boots)) or at('Fire Temple Upper', True))",
"Fire Lower Locked Door": "(Small_Key_Fire_Temple, 5) and (is_adult or Kokiri_Sword)",
"Fire Big Lava Room": "
(logic_fewer_tunic_requirements or can_use(Goron_Tunic)) and can_use(Megaton_Hammer)"
"Fire Temple Near Boss": "
is_adult and has_fire_source and
(logic_fewer_tunic_requirements or can_use(Goron_Tunic))",
"Fire Temple Lower Locked Door": "
(Small_Key_Fire_Temple, 5) and (is_adult or Kokiri_Sword)",
"Fire Temple Big Lava Room": "
is_adult and Megaton_Hammer and (logic_fewer_tunic_requirements or Goron_Tunic)"
}
},
{
"region_name": "Fire Lower Locked Door",
"region_name": "Fire Temple Near Boss",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Megaton Hammer Chest": "is_adult and (has_explosives or Megaton_Hammer or Hookshot)",
"Fire Temple MQ Near Boss Chest": "
is_adult and
((logic_fire_mq_near_boss and has_fire_source and Bow) or
((Hover_Boots or Hookshot) and
((can_use(Fire_Arrows) and can_break_heated_crate) or
(can_use(Dins_Fire) and
((damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or
Goron_Tunic or Hover_Boots or Bow or Longshot)))))",
"Fire Temple MQ Near Boss Pot 1": "can_use(Hookshot) or can_use(Hover_Boots)",
"Fire Temple MQ Near Boss Pot 2": "can_use(Hookshot) or can_use(Hover_Boots)",
"Fire Temple MQ Near Boss Left Crate 1": "can_break_heated_crate",
"Fire Temple MQ Near Boss Left Crate 2": "can_break_heated_crate",
"Fire Temple MQ Near Boss Right Lower Crate 1": "
(can_use(Hookshot) or can_use(Hover_Boots)) and can_break_heated_crate",
"Fire Temple MQ Near Boss Right Lower Crate 2": "
(can_use(Hookshot) or can_use(Hover_Boots)) and can_break_heated_crate",
"Fire Temple MQ Near Boss Right Mid Crate": "
(can_use(Hookshot) or can_use(Hover_Boots)) and can_break_heated_crate",
"Fire Temple MQ Near Boss Right Upper Crate": "
(can_use(Hookshot) or can_use(Hover_Boots)) and can_break_heated_crate"
},
"exits": {
"Fire Temple Boss Door": "
is_adult and (fire_temple_shortcuts or logic_fire_boss_door_jump or Hover_Boots)"
}
},
{
"region_name": "Fire Temple Lower Locked Door",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Megaton Hammer Chest": "
is_adult and (has_explosives or Megaton_Hammer or Hookshot)",
"Fire Temple MQ Map Chest": "can_use(Megaton_Hammer)",
"Fire Temple MQ Iron Knuckle Room Pot 1": "True",
"Fire Temple MQ Iron Knuckle Room Pot 2": "True",
"Fire Temple MQ Iron Knuckle Room Pot 3": "True",
"Fire Temple MQ Iron Knuckle Room Pot 4": "True",
"Fairy Pot": "has_bottle"
}
},
{
"region_name": "Fire Big Lava Room",
"region_name": "Fire Temple Big Lava Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Boss Key Chest": "
has_fire_source and (Bow or logic_fire_mq_bk_chest) and can_use(Hookshot)",
has_fire_source and (Bow or logic_fire_mq_bk_chest) and Hookshot",
"Fire Temple MQ Big Lava Room Blocked Door Chest": "
has_fire_source and has_explosives and
(can_use(Hookshot) or logic_fire_mq_blocked_chest)",
(Hookshot or logic_fire_mq_blocked_chest) and has_explosives and has_fire_source",
"Fire Temple MQ Big Lava Room Left Pot": "True",
"Fire Temple MQ Big Lava Room Right Pot": "Hookshot or logic_fire_mq_blocked_chest",
"Fire Temple MQ Big Lava Room Alcove Pot": "True",
"Fire Temple MQ Boss Key Chest Room Pot": "
has_fire_source and (Bow or logic_fire_mq_bk_chest) and Hookshot",
"Fire Temple MQ GS Big Lava Room Open Door": "True",
"Fairy Pot": "
has_bottle and has_fire_source and (Bow or logic_fire_mq_bk_chest) and
(can_use(Hookshot) or logic_fire_song_of_time)"
(Hookshot or logic_fire_song_of_time)"
},
"exits": {
"Fire Lower Maze": "
can_use(Goron_Tunic) and (Small_Key_Fire_Temple, 2) and
(has_fire_source or (logic_fire_mq_climb and Hover_Boots))"
"Fire Temple Elevator Room": "Goron_Tunic and (Small_Key_Fire_Temple, 2)"
}
},
{
"region_name": "Fire Lower Maze",
"region_name": "Fire Temple Elevator Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Elevator Room Recovery Heart 1": "True",
"Fire Temple MQ Elevator Room Recovery Heart 2": "True",
"Fire Temple MQ Elevator Room Recovery Heart 3": "True"
},
"exits": {
"Fire Temple Lower Lizalfos Maze": "has_fire_source or (logic_fire_mq_climb and Hover_Boots)"
}
},
{
"region_name": "Fire Temple Lower Lizalfos Maze",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Lizalfos Maze Lower Chest": "True",
"Fire Temple MQ Lizalfos Maze Side Room Chest": "
has_explosives and (logic_fire_mq_maze_side_room or at('Fire Upper Maze', True))"
has_explosives and
(logic_fire_mq_maze_side_room or at('Fire Temple Upper Lizalfos Maze', True))",
"Fire Temple MQ Lower Lizalfos Maze Crate 1": "True",
"Fire Temple MQ Lower Lizalfos Maze Crate 2": "True",
"Fire Temple MQ Lower Lizalfos Maze Crate 3": "True"
},
"exits": {
"Fire Upper Maze": "
((has_explosives or logic_rusted_switches) and can_use(Hookshot)) or
(logic_fire_mq_maze_hovers and can_use(Hover_Boots)) or logic_fire_mq_maze_jump"
"Fire Temple Upper Lizalfos Maze": "
((has_explosives or logic_rusted_switches) and Hookshot) or
(logic_fire_mq_maze_hovers and Hover_Boots) or logic_fire_mq_maze_jump"
}
},
{
"region_name": "Fire Upper Maze",
"region_name": "Fire Temple Upper Lizalfos Maze",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Lizalfos Maze Upper Chest": "True",
"Fire Temple MQ Compass Chest": "has_explosives",
"Fire Temple MQ GS Skull On Fire": "
(can_play(Song_of_Time) and can_use(Hookshot) and (has_explosives or logic_rusted_switches)) or
can_use(Longshot)",
"Wall Fairy": "
has_bottle and
((can_play(Song_of_Time) and can_use(Hookshot) and (has_explosives or logic_rusted_switches)) or
can_use(Longshot))",
"Fairy Pot": "has_bottle and (Small_Key_Fire_Temple, 3)"
"Fire Temple MQ Upper Lizalfos Maze Crate 1": "True",
"Fire Temple MQ Upper Lizalfos Maze Crate 2": "True",
"Fire Temple MQ Upper Lizalfos Maze Crate 3": "True"
},
"exits": {
"Fire Temple Upper": "
(Small_Key_Fire_Temple, 3) and
((can_use(Bow) and can_use(Hookshot)) or can_use(Fire_Arrows))"
"Fire Temple Shortcut": "has_explosives",
"Fire Temple Block On Fire Room": "
(Longshot or (can_play(Song_of_Time) and Hookshot)) and
(has_explosives or logic_rusted_switches or (Longshot and logic_fire_scarecrow))",
"Fire Temple Shoot Torch On Wall Room": "(Small_Key_Fire_Temple, 3)"
}
},
{
"region_name": "Fire Temple Shortcut",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Compass Chest": "True",
"Fire Temple MQ Shortcut Crate 1": "True",
"Fire Temple MQ Shortcut Crate 2": "True",
"Fire Temple MQ Shortcut Crate 3": "True",
"Fire Temple MQ Shortcut Crate 4": "True",
"Fire Temple MQ Shortcut Crate 5": "True",
"Fire Temple MQ Shortcut Crate 6": "True"
}
},
{
"region_name": "Fire Temple Block On Fire Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ GS Skull On Fire": "True",
"Wall Fairy": "has_bottle"
},
"exits": {
"Fire Temple Narrow Path Room": "
(damage_multiplier != 'ohko' and damage_multiplier != 'quadruple') or
Fairy or can_use(Nayrus_Love)"
}
},
{
"region_name": "Fire Temple Narrow Path Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Narrow Path Room Pot 1": "True",
"Fire Temple MQ Narrow Path Room Pot 2": "True",
"Fairy Pot": "has_bottle"
}
},
{
"region_name": "Fire Temple Shoot Torch On Wall Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Shoot Torch On Wall Room Pot 1": "True",
"Fire Temple MQ Shoot Torch On Wall Room Pot 2": "True",
"Fire Temple MQ Shoot Torch On Wall Room Right Crate 1": "True",
"Fire Temple MQ Shoot Torch On Wall Room Right Crate 2": "True",
"Fire Temple MQ Shoot Torch On Wall Room Center Crate": "True",
"Fire Temple MQ Shoot Torch On Wall Room Left Crate 1": "True",
"Fire Temple MQ Shoot Torch On Wall Room Left Crate 2": "True"
},
"exits": {
"Fire Temple Narrow Path Room": "True",
"Fire Temple Flame Maze": "(can_use(Bow) and can_use(Hookshot)) or can_use(Fire_Arrows)"
}
},
{
"region_name": "Fire Temple Flame Maze",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Flame Maze Left Pot 1": "True",
"Fire Temple MQ GS Flame Maze Center": "has_explosives",
"Fire Temple MQ GS Above Flame Maze": "
(Hookshot and (Small_Key_Fire_Temple, 5)) or
(logic_fire_mq_above_maze_gs and Longshot)"
},
"exits": {
"Fire Temple Near Boss": "True",
"Fire Temple Flame Maze Side Room": "
can_play(Song_of_Time) or Hover_Boots or logic_fire_mq_flame_maze",
"Fire Temple Upper": "Hookshot or logic_fire_mq_flame_maze",
"Fire Temple Boss Door": "True"
}
},
{
"region_name": "Fire Temple Flame Maze Side Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Flame Maze Right Pot 1": "True",
"Fire Temple MQ Flame Maze Right Pot 2": "True",
"Fire Temple MQ GS Flame Maze Side Room": "True"
}
},
{
"region_name": "Fire Temple Upper",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple MQ Freestanding Key": "can_use(Hookshot) or logic_fire_mq_flame_maze",
"Fire Temple MQ Chest On Fire": "
(can_use(Hookshot) or logic_fire_mq_flame_maze) and (Small_Key_Fire_Temple, 4)",
"Fire Temple MQ GS Fire Wall Maze Side Room": "
can_play(Song_of_Time) or Hover_Boots or logic_fire_mq_flame_maze",
"Fire Temple MQ GS Fire Wall Maze Center": "has_explosives",
"Fire Temple MQ GS Above Fire Wall Maze": "
(can_use(Hookshot) and (Small_Key_Fire_Temple, 5)) or
(logic_fire_mq_above_maze_gs and can_use(Longshot))"
}
},
{
"region_name": "Fire Boss Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Volvagia Heart": "True",
"Volvagia": "True"
"Fire Temple MQ Freestanding Key": "True",
"Fire Temple MQ Chest On Fire": "(Small_Key_Fire_Temple, 4)",
"Fire Temple MQ Flame Maze Right Upper Pot 1": "True",
"Fire Temple MQ Flame Maze Right Upper Pot 2": "True"
}
}
]

View File

@ -5,29 +5,35 @@
"locations": {
"Fire Temple Near Boss Chest": "
logic_fewer_tunic_requirements or can_use(Goron_Tunic)",
"Fire Temple Flare Dancer Chest": "
((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)",
"Fire Temple Boss Key Chest": "
((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)",
"Fire Temple Volvagia Heart": "
can_use(Goron_Tunic) and can_use(Megaton_Hammer) and Boss_Key_Fire_Temple and
(logic_fire_boss_door_jump or Hover_Boots or
at('Fire Temple Upper', can_play(Song_of_Time) or has_explosives))",
"Volvagia": "
can_use(Goron_Tunic) and can_use(Megaton_Hammer) and Boss_Key_Fire_Temple and
(logic_fire_boss_door_jump or Hover_Boots or
at('Fire Temple Upper', can_play(Song_of_Time) or has_explosives))",
"Fire Temple GS Boss Key Loop": "
((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)",
"Fire Temple Near Boss Pot 1": "
is_adult and (Hover_Boots or Hookshot) and
(logic_fewer_tunic_requirements or Goron_Tunic)",
"Fire Temple Near Boss Pot 2": "
is_adult and (Hover_Boots or Hookshot) and
(logic_fewer_tunic_requirements or Goron_Tunic)",
"Fairy Pot": "
has_bottle and (can_use(Hover_Boots) or can_use(Hookshot)) and
(logic_fewer_tunic_requirements or can_use(Goron_Tunic))"
is_adult and has_bottle and (Hover_Boots or Hookshot) and
(logic_fewer_tunic_requirements or Goron_Tunic)"
},
"exits": {
"DMC Fire Temple Entrance": "True",
"Fire Temple Big Lava Room": "
(Small_Key_Fire_Temple, 2) and
(logic_fewer_tunic_requirements or can_use(Goron_Tunic))"
(logic_fewer_tunic_requirements or can_use(Goron_Tunic))",
"Fire Temple Lower Locked Door": "
((Small_Key_Fire_Temple, 8) or not keysanity) and can_use(Megaton_Hammer)",
"Fire Temple Boss Door": "
is_adult and (logic_fewer_tunic_requirements or Goron_Tunic) and
(fire_temple_shortcuts or logic_fire_boss_door_jump or Hover_Boots)"
}
},
{
"region_name": "Fire Temple Lower Locked Door",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Flare Dancer Chest": "True",
"Fire Temple Boss Key Chest": "True",
"Fire Temple GS Boss Key Loop": "True"
}
},
{
@ -36,45 +42,91 @@
"locations": {
"Fire Temple Big Lava Room Lower Open Door Chest": "True",
"Fire Temple Big Lava Room Blocked Door Chest": "is_adult and has_explosives",
"Fire Temple Big Lava Room Pot 1": "True",
"Fire Temple Big Lava Room Pot 2": "True",
"Fire Temple Big Lava Room Pot 3": "True",
"Fire Temple GS Song of Time Room": "
is_adult and (can_play(Song_of_Time) or logic_fire_song_of_time)"
},
"exits": {
"Fire Temple Lower": "True",
"Fire Temple Middle": "
can_use(Goron_Tunic) and (Small_Key_Fire_Temple, 4) and
(Progressive_Strength_Upgrade or logic_fire_strength) and
(has_explosives or Bow or Progressive_Hookshot)"
"Fire Temple Elevator Room": "
is_adult and Goron_Tunic and (Small_Key_Fire_Temple, 3)"
}
},
{
"region_name": "Fire Temple Middle",
"region_name": "Fire Temple Elevator Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Elevator Room Recovery Heart 1": "True",
"Fire Temple Elevator Room Recovery Heart 2": "True",
"Fire Temple Elevator Room Recovery Heart 3": "True"
},
"exits": {
"Fire Temple Boulder Maze Lower": "
(Small_Key_Fire_Temple, 4) and
(Progressive_Strength_Upgrade or logic_fire_strength) and
(has_explosives or Bow or Hookshot)"
}
},
{
"region_name": "Fire Temple Boulder Maze Lower",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Boulder Maze Lower Chest": "True",
"Fire Temple Boulder Maze Upper Chest": "(Small_Key_Fire_Temple, 6)",
"Fire Temple Boulder Maze Side Room Chest": "True",
"Fire Temple Boulder Maze Shortcut Chest": "
(Small_Key_Fire_Temple, 6) and has_explosives",
"Fire Temple GS Boulder Maze": "has_explosives"
},
"exits": {
"Fire Temple Narrow Path Room": "(Small_Key_Fire_Temple, 5)"
}
},
{
"region_name": "Fire Temple Narrow Path Room",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Map Chest": "Bow or (Small_Key_Fire_Temple, 6)",
"Fire Temple Narrow Path Room Recovery Heart 1": "True",
"Fire Temple Narrow Path Room Recovery Heart 2": "True",
"Fire Temple Narrow Path Room Recovery Heart 3": "True"
},
"exits": {
"Fire Temple Boulder Maze Upper": "(Small_Key_Fire_Temple, 6)"
}
},
{
"region_name": "Fire Temple Boulder Maze Upper",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Boulder Maze Upper Chest": "True",
"Fire Temple Boulder Maze Shortcut Chest": "has_explosives",
"Fire Temple Scarecrow Chest": "
(Small_Key_Fire_Temple, 6) and
(can_use(Scarecrow) or (logic_fire_scarecrow and can_use(Longshot)))",
"Fire Temple Map Chest": "
(Small_Key_Fire_Temple, 6) or ((Small_Key_Fire_Temple, 5) and can_use(Bow))",
"Fire Temple Compass Chest": "(Small_Key_Fire_Temple, 7)",
"Fire Temple GS Boulder Maze": "(Small_Key_Fire_Temple, 4) and has_explosives",
can_use(Scarecrow) or (logic_fire_scarecrow and Longshot)",
"Fire Temple Moving Fire Room Recovery Heart 1": "True",
"Fire Temple Moving Fire Room Recovery Heart 2": "True",
"Fire Temple Moving Fire Room Recovery Heart 3": "True",
"Fire Temple GS Scarecrow Climb": "
(Small_Key_Fire_Temple, 6) and
(can_use(Scarecrow) or (logic_fire_scarecrow and can_use(Longshot)))",
can_use(Scarecrow) or (logic_fire_scarecrow and Longshot)",
"Fire Temple GS Scarecrow Top": "
(Small_Key_Fire_Temple, 6) and
(can_use(Scarecrow) or (logic_fire_scarecrow and can_use(Longshot)))"
can_use(Scarecrow) or (logic_fire_scarecrow and Longshot)"
},
"exits": {
"Fire Temple Flame Maze": "(Small_Key_Fire_Temple, 7)"
}
},
{
"region_name": "Fire Temple Flame Maze",
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Compass Chest": "True",
"Fire Temple Flame Maze Left Side Pot 1": "True",
"Fire Temple Flame Maze Left Side Pot 2": "True",
"Fire Temple Flame Maze Left Side Pot 3": "True",
"Fire Temple Flame Maze Left Side Pot 4": "True"
},
"exits": {
"Fire Temple Upper": "
(Small_Key_Fire_Temple, 8) or
((Small_Key_Fire_Temple, 7) and
((can_use(Hover_Boots) and can_use(Megaton_Hammer)) or logic_fire_flame_maze))"
(Hover_Boots and Megaton_Hammer) or logic_fire_flame_maze"
}
},
{
@ -82,10 +134,18 @@
"dungeon": "Fire Temple",
"locations": {
"Fire Temple Highest Goron Chest": "
can_use(Megaton_Hammer) and
(can_play(Song_of_Time) or (logic_rusted_switches and
(can_use(Hover_Boots) or has_explosives)))",
"Fire Temple Megaton Hammer Chest": "has_explosives"
Megaton_Hammer and
(can_play(Song_of_Time) or
(logic_rusted_switches and (Hover_Boots or has_explosives)))",
"Fire Temple Megaton Hammer Chest": "has_explosives",
"Fire Temple Flame Maze Right Side Pot 1": "True",
"Fire Temple Flame Maze Right Side Pot 2": "True",
"Fire Temple Flame Maze Right Side Pot 3": "True",
"Fire Temple Flame Maze Right Side Pot 4": "True"
},
"exits": {
"Fire Temple Boss Door": "
Megaton_Hammer and (can_play(Song_of_Time) or has_explosives)"
}
}
]

View File

@ -22,44 +22,77 @@
(can_play(Song_of_Time) or is_child) and
(is_adult or can_use(Dins_Fire) or
can_use(Sticks) or can_use(Slingshot) or Kokiri_Sword)",
"Forest Temple MQ GS Block Push Room": "is_adult or Kokiri_Sword",
"Forest Temple MQ Center Room Right Pot 1": "True",
"Forest Temple MQ Center Room Right Pot 2": "True",
"Forest Temple MQ Center Room Right Pot 3": "True",
"Forest Temple MQ Center Room Left Pot 1": "True",
"Forest Temple MQ Center Room Left Pot 2": "True",
"Forest Temple MQ Center Room Left Pot 3": "True",
"Forest Temple MQ Wolfos Room Pot": "(can_play(Song_of_Time) or is_child)",
"Fairy Pot": "has_bottle and (can_play(Song_of_Time) or is_child)"
},
"exits": {
"Forest Temple NW Outdoors": "can_use(Bow) or can_use(Slingshot)",
"Forest Temple NE Outdoors": "can_use(Bow) or can_use(Slingshot)",
# End of the road for child
"Forest Temple Before Block Puzzle": "here(is_adult or Kokiri_Sword)",
"Forest Temple Before Boss": "
(Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg) or forest_temple_shortcuts"
}
},
{
"region_name": "Forest Temple Before Block Puzzle",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ GS Block Push Room": "True"
},
"exits": {
"Forest Temple After Block Puzzle": "
is_adult and (Progressive_Strength_Upgrade or
(logic_forest_mq_block_puzzle and has_bombchus and can_use(Hookshot)))",
"Forest Temple Outdoor Ledge": "
(logic_forest_mq_hallway_switch_jumpslash and can_use(Hover_Boots))",
"Forest Temple Boss Region": "
Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg"
(logic_forest_mq_block_puzzle and has_bombchus and Hookshot))",
# Child cannot climb these large blocks
"Forest Temple Outside Upper Ledge": "
(at('Forest Temple Outside Upper Ledge', True) or
here((logic_forest_mq_hallway_switch_boomerang and can_use(Boomerang)) or
(logic_forest_mq_hallway_switch_jumpslash and
(can_use(Hover_Boots) or
(((logic_forest_mq_block_puzzle and has_bombchus) or
(Progressive_Strength_Upgrade and (is_adult or Slingshot))) and
(Progressive_Strength_Upgrade or can_use(Hookshot)) and
(is_adult or Sticks)))))) and
(can_use(Hover_Boots) or can_use(Hookshot) or
(Progressive_Strength_Upgrade and
logic_forest_outside_backdoor and can_jumpslash))"
}
},
{
"region_name": "Forest Temple After Block Puzzle",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ Boss Key Chest": "(Small_Key_Forest_Temple, 3)"
},
"exits": {
"Forest Temple Bow Region": "(Small_Key_Forest_Temple, 4)",
"Forest Temple Outdoor Ledge": "
(Small_Key_Forest_Temple, 3) or
(logic_forest_mq_hallway_switch_jumpslash and
(can_use(Hookshot) or logic_forest_outside_backdoor))",
"Forest Temple Straightened Hall": "(Small_Key_Forest_Temple, 3)",
"Forest Temple NW Outdoors": "(Small_Key_Forest_Temple, 2)"
# Only 2 keys because you must have had access to falling ceiling room to have wasted a key there
# and access to falling ceiling room means you must also have had to access to the lower area of this courtyard
# Access to falling ceiling room means you must also have had to access to the lower area of this courtyard
}
},
{
"region_name": "Forest Temple Outdoor Ledge",
"region_name": "Forest Temple Straightened Hall",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ Redead Chest": "True"
"Forest Temple MQ Boss Key Chest": "True"
},
"exits": {
"Forest Temple Outside Upper Ledge": "True",
"Forest Temple Bow Region": "(Small_Key_Forest_Temple, 4)"
}
},
{
"region_name": "Forest Temple Outside Upper Ledge",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ Redead Chest": "True",
"Forest Temple MQ Courtyard Recovery Heart 1": "True",
"Forest Temple MQ Courtyard Recovery Heart 2": "True",
"Forest Temple MQ Courtyard Recovery Heart 3": "True"
},
"exits": {
"Forest Temple NW Outdoors": "True"
@ -75,7 +108,7 @@
"Forest Temple NE Outdoors": "
can_use(Iron_Boots) or can_use(Longshot) or
(Progressive_Scale, 2) or (logic_forest_well_swim and can_use(Hookshot))",
"Forest Temple Outdoors Top Ledges": "can_use(Fire_Arrows)"
"Forest Temple Outdoors High Balconies": "can_use(Fire_Arrows)"
}
},
{
@ -83,6 +116,9 @@
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ Well Chest": "can_use(Bow) or can_use(Slingshot)",
"Forest Temple MQ Well Recovery Heart 1": "can_use(Iron_Boots) or can_use(Bow) or can_use(Slingshot)",
"Forest Temple MQ Well Recovery Heart 2": "can_use(Iron_Boots) or can_use(Bow) or can_use(Slingshot)",
"Forest Temple MQ Well Recovery Heart 3": "can_use(Iron_Boots) or can_use(Bow) or can_use(Slingshot)",
"Forest Temple MQ GS Raised Island Courtyard": "
can_use(Hookshot) or can_use(Boomerang) or
(can_use(Fire_Arrows) and
@ -95,7 +131,7 @@
has_explosives or Kokiri_Sword or can_use(Dins_Fire)"
},
"exits": {
"Forest Temple Outdoors Top Ledges": "
"Forest Temple Outdoors High Balconies": "
can_use(Hookshot) and
(can_use(Longshot) or can_use(Hover_Boots) or can_play(Song_of_Time) or
logic_forest_vines)",
@ -103,7 +139,7 @@
}
},
{
"region_name": "Forest Temple Outdoors Top Ledges",
"region_name": "Forest Temple Outdoors High Balconies",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ Raised Island Courtyard Upper Chest": "True"
@ -133,7 +169,17 @@
"locations": {
"Forest Temple MQ Bow Chest": "True",
"Forest Temple MQ Map Chest": "can_use(Bow)",
"Forest Temple MQ Compass Chest": "can_use(Bow)"
"Forest Temple MQ Compass Chest": "can_use(Bow)",
"Forest Temple MQ Upper Stalfos Pot 1": "True",
"Forest Temple MQ Upper Stalfos Pot 2": "True",
"Forest Temple MQ Upper Stalfos Pot 3": "True",
"Forest Temple MQ Upper Stalfos Pot 4": "True",
"Forest Temple MQ Blue Poe Room Pot 1": "True",
"Forest Temple MQ Blue Poe Room Pot 2": "True",
"Forest Temple MQ Blue Poe Room Pot 3": "True",
"Forest Temple MQ Frozen Eye Switch Room Small Wooden Crate 1": "(Small_Key_Forest_Temple, 6)",
"Forest Temple MQ Frozen Eye Switch Room Small Wooden Crate 2": "(Small_Key_Forest_Temple, 6)",
"Forest Temple MQ Frozen Eye Switch Room Small Wooden Crate 3": "(Small_Key_Forest_Temple, 6)"
},
"exits": {
"Forest Temple Falling Room": "
@ -148,19 +194,26 @@
"Forest Temple Amy and Meg": "can_use(Bow) and (Small_Key_Forest_Temple, 6)"
},
"locations": {
"Forest Temple MQ Falling Ceiling Room Chest": "True"
"Forest Temple MQ Falling Ceiling Room Chest": "True",
"Forest Temple MQ Green Poe Room Pot 1": "(Small_Key_Forest_Temple, 6)",
"Forest Temple MQ Green Poe Room Pot 2": "(Small_Key_Forest_Temple, 6)"
},
"exits": {
"Forest Temple NE Outdoors Ledge": "True"
}
},
{
"region_name": "Forest Temple Boss Region",
"region_name": "Forest Temple Before Boss",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple MQ Basement Chest": "True",
"Forest Temple Phantom Ganon Heart": "Boss_Key_Forest_Temple",
"Phantom Ganon": "Boss_Key_Forest_Temple"
"Forest Temple MQ Basement Pot 1": "True",
"Forest Temple MQ Basement Pot 2": "True",
"Forest Temple MQ Basement Pot 3": "True",
"Forest Temple MQ Basement Pot 4": "True"
},
"exits": {
"Forest Temple Boss Door": "True"
}
}
]

View File

@ -4,20 +4,36 @@
"dungeon": "Forest Temple",
"locations": {
"Forest Temple First Room Chest": "True",
"Forest Temple First Stalfos Chest": "is_adult or Kokiri_Sword",
"Forest Temple GS First Room": "
(is_adult and (Hookshot or Bow or Bombs)) or (is_child and (Boomerang or Slingshot)) or
has_bombchus or can_use(Dins_Fire) or (logic_forest_first_gs and (Bombs or
(can_jumpslash and can_take_damage)))",
"Forest Temple GS Lobby": "can_use(Hookshot) or can_use(Boomerang)",
"Fairy Pot": "has_bottle and (is_adult or can_child_attack or Nuts)"
has_bombchus or can_use(Dins_Fire) or (logic_forest_first_gs and (Bombs or can_jumpslash))"
},
"exits": {
"SFM Forest Temple Entrance Ledge": "True",
"Forest Temple Central Area": "is_adult or can_child_attack or Nuts"
}
},
{
"region_name": "Forest Temple Central Area",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple First Stalfos Chest": "is_adult or Kokiri_Sword",
"Forest Temple Center Room Right Pot 1": "True",
"Forest Temple Center Room Right Pot 2": "True",
"Forest Temple Center Room Right Pot 3": "True",
"Forest Temple Center Room Left Pot 1": "True",
"Forest Temple Center Room Left Pot 2": "True",
"Forest Temple Center Room Left Pot 3": "True",
"Forest Temple Lower Stalfos Pot": "True",
"Forest Temple GS Lobby": "can_use(Hookshot) or can_use(Boomerang)",
"Fairy Pot": "has_bottle"
},
"exits": {
"Forest Temple NW Outdoors": "can_play(Song_of_Time) or is_child",
"Forest Temple NE Outdoors": "can_use(Bow) or can_use(Slingshot)",
"Forest Temple Block Push Room": "(Small_Key_Forest_Temple, 1)",
"Forest Temple Boss Region": "Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg"
"Forest Temple Before Boss": "
(Forest_Temple_Jo_and_Beth and Forest_Temple_Amy_and_Meg) or forest_temple_shortcuts"
}
},
{
@ -26,7 +42,7 @@
"locations": {
"Forest Temple GS Level Island Courtyard": "
can_use(Longshot) or
at('Forest Temple Outside Upper Ledge', can_use(Hookshot))",
at('Forest Temple Outside Upper Ledge', can_use(Hookshot) or can_use(Boomerang))",
"Deku Baba Sticks": "is_adult or Kokiri_Sword or Boomerang",
"Deku Baba Nuts": "
is_adult or Slingshot or Sticks or
@ -37,8 +53,23 @@
# Other methods of crossing through the well are not currently relevant.
"Forest Temple Outdoors High Balconies": "
here(is_adult or has_explosives or
((Boomerang or Nuts or Deku_Shield) and
(Sticks or Kokiri_Sword or Slingshot)))"
((Boomerang or Nuts or Deku_Shield) and (Sticks or Kokiri_Sword or Slingshot)))"
}
},
{
"region_name": "Forest Temple Outdoors High Balconies",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Well Chest": "True",
"Forest Temple Map Chest": "True",
"Forest Temple Well Recovery Heart 1": "True",
"Forest Temple Well Recovery Heart 2": "True"
},
"exits": {
"Forest Temple NW Outdoors": "True",
"Forest Temple NE Outdoors": "True",
"Forest Temple Falling Room": "
logic_forest_door_frame and can_use(Hover_Boots) and can_use(Scarecrow)"
}
},
{
@ -46,9 +77,9 @@
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Raised Island Courtyard Chest": "
can_use(Hookshot) or
at('Forest Temple Falling Room', True) or
(logic_forest_outdoors_ledge and can_use(Hover_Boots) and at('Forest Temple Outdoors High Balconies', True))",
can_use(Hookshot) or at('Forest Temple Falling Room', True) or
(logic_forest_outdoors_ledge and can_use(Hover_Boots) and
at('Forest Temple Outdoors High Balconies', True))",
"Forest Temple GS Raised Island Courtyard": "
can_use(Hookshot) or (logic_forest_outdoor_east_gs and can_use(Boomerang)) or
at('Forest Temple Falling Room', can_use(Bow) or can_use(Dins_Fire) or has_explosives)",
@ -61,35 +92,7 @@
"Forest Temple Outdoors High Balconies": "
can_use(Longshot) or (logic_forest_vines and can_use(Hookshot))",
# Longshot can grab some very high up vines to drain the well.
"Forest Temple NW Outdoors": "can_use(Iron_Boots) or (Progressive_Scale, 2)",
"Forest Temple Lobby": "True"
}
},
{
"region_name": "Forest Temple Outdoors High Balconies",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Well Chest": "True",
"Forest Temple Map Chest": "True"
},
"exits": {
"Forest Temple NW Outdoors": "True",
"Forest Temple NE Outdoors": "True",
"Forest Temple Falling Room": "
logic_forest_door_frame and can_use(Hover_Boots) and can_use(Scarecrow)"
}
},
{
"region_name": "Forest Temple Falling Room",
"dungeon": "Forest Temple",
"events": {
"Forest Temple Amy and Meg": "can_use(Bow)"
},
"locations": {
"Forest Temple Falling Ceiling Room Chest": "True"
},
"exits": {
"Forest Temple NE Outdoors": "True"
"Forest Temple NW Outdoors": "can_use(Iron_Boots) or (Progressive_Scale, 2)"
}
},
{
@ -100,13 +103,14 @@
Progressive_Strength_Upgrade and (can_use(Bow) or can_use(Slingshot))"
},
"exits": {
#end of the road for child forest. No hovers and too short to climb push blocks
"Forest Temple Outside Upper Ledge": "
can_use(Hover_Boots) or (logic_forest_outside_backdoor and is_adult and Progressive_Strength_Upgrade)",
can_use(Hover_Boots) or
(logic_forest_outside_backdoor and Progressive_Strength_Upgrade and can_jumpslash)",
"Forest Temple Bow Region": "
Progressive_Strength_Upgrade and (Small_Key_Forest_Temple, 3) and is_adult",
"Forest Temple Straightened Hall": "
Progressive_Strength_Upgrade and (Small_Key_Forest_Temple, 2) and can_use(Bow)"
# Child cannot climb these large blocks
}
},
{
@ -123,7 +127,9 @@
"region_name": "Forest Temple Outside Upper Ledge",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Floormaster Chest": "True"
"Forest Temple Floormaster Chest": "True",
"Forest Temple Courtyard Recovery Heart 1": "True",
"Forest Temple Courtyard Recovery Heart 2": "True"
},
"exits": {
"Forest Temple NW Outdoors": "True"
@ -138,21 +144,54 @@
"locations": {
"Forest Temple Bow Chest": "True",
"Forest Temple Red Poe Chest": "can_use(Bow)",
"Forest Temple Blue Poe Chest": "can_use(Bow)"
"Forest Temple Blue Poe Chest": "can_use(Bow)",
"Forest Temple Upper Stalfos Pot 1": "True",
"Forest Temple Upper Stalfos Pot 2": "True",
"Forest Temple Upper Stalfos Pot 3": "True",
"Forest Temple Upper Stalfos Pot 4": "True",
"Forest Temple Blue Poe Room Pot 1": "True",
"Forest Temple Blue Poe Room Pot 2": "True",
"Forest Temple Blue Poe Room Pot 3": "True"
},
"exits": {
"Forest Temple Falling Room": "
(Small_Key_Forest_Temple, 5) and (Bow or can_use(Dins_Fire))"
"Forest Temple Frozen Eye Switch Room": "(Small_Key_Forest_Temple, 5)"
}
},
{
"region_name": "Forest Temple Boss Region",
"region_name": "Forest Temple Frozen Eye Switch Room",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Frozen Eye Switch Room Pot 1": "True",
"Forest Temple Frozen Eye Switch Room Pot 2": "True"
},
"exits": {
"Forest Temple Falling Room": "Bow or can_use(Dins_Fire)"
}
},
{
"region_name": "Forest Temple Falling Room",
"dungeon": "Forest Temple",
"events": {
"Forest Temple Amy and Meg": "can_use(Bow)"
},
"locations": {
"Forest Temple Falling Ceiling Room Chest": "True",
"Forest Temple Green Poe Room Pot 1": "True",
"Forest Temple Green Poe Room Pot 2": "True"
},
"exits": {
"Forest Temple NE Outdoors": "True"
}
},
{
"region_name": "Forest Temple Before Boss",
"dungeon": "Forest Temple",
"locations": {
"Forest Temple Basement Chest": "True",
"Forest Temple Phantom Ganon Heart": "Boss_Key_Forest_Temple",
"Phantom Ganon": "Boss_Key_Forest_Temple",
"Forest Temple GS Basement": "can_use(Hookshot) or can_use(Boomerang)"
},
"exits": {
"Forest Temple Boss Door": "True"
}
}
]

View File

@ -3,21 +3,187 @@
"region_name": "Ganons Castle Lobby",
"dungeon": "Ganons Castle",
"exits": {
"Castle Grounds": "True",
"Ganons Castle Forest Trial": "True",
"Ganons Castle Fire Trial": "True",
"Castle Grounds From Ganons Castle": "True",
"Ganons Castle Main": "
here(is_adult or
(Kokiri_Sword and (Sticks or has_explosives or Nuts or Boomerang)) or
(has_explosives and (Sticks or ((Nuts or Boomerang) and Slingshot))))"
}
},
{
"region_name": "Ganons Castle Main",
"dungeon": "Ganons Castle",
"exits": {
"Ganons Castle Forest Trial": "here(is_adult or Kokiri_Sword)",
"Ganons Castle Water Trial": "True",
"Ganons Castle Shadow Trial": "True",
"Ganons Castle Spirit Trial": "True",
"Ganons Castle Shadow Trial": "is_adult",
"Ganons Castle Fire Trial": "
is_adult and Goron_Tunic and Golden_Gauntlets and
(Longshot or Hover_Boots or (logic_fire_trial_mq and Hookshot))",
"Ganons Castle Light Trial": "can_use(Golden_Gauntlets)",
"Ganons Castle Spirit Trial": "can_use(Megaton_Hammer) and (Bow or logic_rusted_switches)",
"Ganons Castle Deku Scrubs": "logic_lens_castle_mq or can_use(Lens_of_Truth)",
"Ganons Castle Tower": "
(skipped_trials[Forest] or 'Forest Trial Clear') and
(skipped_trials[Fire] or 'Fire Trial Clear') and
(skipped_trials[Water] or 'Water Trial Clear') and
(skipped_trials[Shadow] or 'Shadow Trial Clear') and
(skipped_trials[Spirit] or 'Spirit Trial Clear') and
(skipped_trials[Light] or 'Light Trial Clear')",
"Ganons Castle Deku Scrubs": "logic_lens_castle_mq or can_use(Lens_of_Truth)"
(skipped_trials[Light] or 'Light Trial Clear')"
}
},
{
"region_name": "Ganons Castle Forest Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Forest Trial Freestanding Key": "can_use(Hookshot) or can_use(Boomerang)",
"Ganons Castle MQ Forest Trial Eye Switch Chest": "can_use(Bow) or can_use(Slingshot)",
"Ganons Castle MQ Forest Trial Frozen Eye Switch Chest": "has_fire_source"
},
"exits": {
"Ganons Castle Forest Trial Ending": "is_adult and can_play(Song_of_Time)"
}
},
{
"region_name": "Ganons Castle Forest Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Forest Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle MQ Forest Trial Pot 1": "True",
"Ganons Castle MQ Forest Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Water Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Water Trial Chest": "Blue_Fire",
"Ganons Castle MQ Water Trial Recovery Heart": "Blue_Fire",
"Blue Fire": "has_bottle"
},
"exits": {
"Ganons Castle Water Trial Ending": "Blue_Fire and (Small_Key_Ganons_Castle, 3)"
}
},
{
"region_name": "Ganons Castle Water Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Water Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle MQ Water Trial Pot 1": "True",
"Ganons Castle MQ Water Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Shadow Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Shadow Trial Bomb Flower Chest": "
(Bow and (Hookshot or Hover_Boots)) or
(Hover_Boots and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and
(has_explosives or Progressive_Strength_Upgrade or can_use(Dins_Fire)))"
},
"exits": {
"Ganons Castle Shadow Trial Ending": "
(logic_lens_castle_mq or can_use(Lens_of_Truth)) and
(Hover_Boots or (Bow and Hookshot and (has_fire_source or logic_shadow_trial_mq)))"
}
},
{
"region_name": "Ganons Castle Shadow Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Shadow Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle MQ Shadow Trial Eye Switch Chest": "Bow",
"Ganons Castle MQ Shadow Trial Pot 1": "True",
"Ganons Castle MQ Shadow Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Fire Trial",
"dungeon": "Ganons Castle",
"events": {
"Fire Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle MQ Fire Trial Pot 1": "True",
"Ganons Castle MQ Fire Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Light Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Light Trial Lullaby Chest": "can_play(Zeldas_Lullaby)"
},
"exits": {
"Ganons Castle Light Trial Boulder Room": "
(Small_Key_Ganons_Castle, 2) and (Hookshot or logic_light_trial_mq)"
}
},
{
"region_name": "Ganons Castle Light Trial Boulder Room",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Light Trial Recovery Heart 1": "True",
"Ganons Castle MQ Light Trial Recovery Heart 2": "True"
},
"exits": {
"Ganons Castle Light Trial Ending": "
(Small_Key_Ganons_Castle, 3) and (logic_lens_castle_mq or can_use(Lens_of_Truth))"
}
},
{
"region_name": "Ganons Castle Light Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Light Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle MQ Light Trial Pot 1": "True",
"Ganons Castle MQ Light Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Spirit Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Spirit Trial First Chest": "True"
},
"exits": {
"Ganons Castle Spirit Trial Second Room": "has_bombchus"
}
},
{
"region_name": "Ganons Castle Spirit Trial Second Room",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle MQ Spirit Trial Invisible Chest": "logic_lens_castle_mq or can_use(Lens_of_Truth)"
},
"exits": {
"Ganons Castle Spirit Trial Ending": "can_use(Fire_Arrows) and Mirror_Shield"
}
},
{
"region_name": "Ganons Castle Spirit Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Spirit Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle MQ Spirit Trial Sun Front Left Chest": "True",
"Ganons Castle MQ Spirit Trial Sun Back Left Chest": "True",
"Ganons Castle MQ Spirit Trial Golden Gauntlets Chest": "True",
"Ganons Castle MQ Spirit Trial Sun Back Right Chest": "True",
"Ganons Castle MQ Spirit Trial Pot 1": "True",
"Ganons Castle MQ Spirit Trial Pot 2": "True",
"Nut Pot": "True"
}
},
{
@ -31,100 +197,5 @@
"Ganons Castle MQ Deku Scrub Right": "True",
"Free Fairies": "has_bottle"
}
},
{
"region_name": "Ganons Castle Forest Trial",
"dungeon": "Ganons Castle",
"events": {
"Forest Trial Clear": "can_use(Light_Arrows) and can_play(Song_of_Time)"
},
"locations": {
"Ganons Castle MQ Forest Trial Eye Switch Chest": "Bow",
"Ganons Castle MQ Forest Trial Frozen Eye Switch Chest": "has_fire_source",
"Ganons Castle MQ Forest Trial Freestanding Key": "Progressive_Hookshot"
}
},
{
"region_name": "Ganons Castle Fire Trial",
"dungeon": "Ganons Castle",
"events": {
"Fire Trial Clear": "
can_use(Goron_Tunic) and can_use(Golden_Gauntlets) and can_use(Light_Arrows) and
(can_use(Longshot) or Hover_Boots or (logic_fire_trial_mq and can_use(Hookshot)))"
}
},
{
"region_name": "Ganons Castle Water Trial",
"dungeon": "Ganons Castle",
"events": {
"Water Trial Clear": "
Blue_Fire and can_use(Light_Arrows) and
(Small_Key_Ganons_Castle, 3)"
},
"locations": {
"Ganons Castle MQ Water Trial Chest": "Blue_Fire",
"Blue Fire": "has_bottle"
}
},
{
"region_name": "Ganons Castle Shadow Trial",
"dungeon": "Ganons Castle",
"events": {
"Shadow Trial Clear": "
can_use(Light_Arrows) and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and
(Hover_Boots or (Progressive_Hookshot and (has_fire_source or logic_shadow_trial_mq)))"
},
"locations": {
"Ganons Castle MQ Shadow Trial Bomb Flower Chest": "
(Bow and (Progressive_Hookshot or Hover_Boots)) or
(Hover_Boots and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and
(has_explosives or Progressive_Strength_Upgrade or can_use(Dins_Fire)))",
"Ganons Castle MQ Shadow Trial Eye Switch Chest": "
Bow and (logic_lens_castle_mq or can_use(Lens_of_Truth)) and
(Hover_Boots or (Progressive_Hookshot and (has_fire_source or logic_shadow_trial_mq)))"
}
},
{
"region_name": "Ganons Castle Spirit Trial",
"dungeon": "Ganons Castle",
"events": {
"Spirit Trial Clear": "
can_use(Light_Arrows) and Megaton_Hammer and
has_bombchus and Fire_Arrows and Mirror_Shield"
},
"locations": {
"Ganons Castle MQ Spirit Trial First Chest": "(Bow or logic_rusted_switches) and Megaton_Hammer",
"Ganons Castle MQ Spirit Trial Invisible Chest": "
(Bow or logic_rusted_switches) and Megaton_Hammer and
has_bombchus and (logic_lens_castle_mq or can_use(Lens_of_Truth))",
"Ganons Castle MQ Spirit Trial Sun Front Left Chest": "
Megaton_Hammer and has_bombchus and
can_use(Fire_Arrows) and Mirror_Shield",
"Ganons Castle MQ Spirit Trial Sun Back Left Chest": "
Megaton_Hammer and has_bombchus and
can_use(Fire_Arrows) and Mirror_Shield",
"Ganons Castle MQ Spirit Trial Golden Gauntlets Chest": "
Megaton_Hammer and has_bombchus and
can_use(Fire_Arrows) and Mirror_Shield",
"Ganons Castle MQ Spirit Trial Sun Back Right Chest": "
Megaton_Hammer and has_bombchus and
can_use(Fire_Arrows) and Mirror_Shield",
"Nut Pot": "
Megaton_Hammer and has_bombchus and
can_use(Fire_Arrows) and Mirror_Shield"
}
},
{
"region_name": "Ganons Castle Light Trial",
"dungeon": "Ganons Castle",
"events": {
"Light Trial Clear": "
can_use(Light_Arrows) and (Small_Key_Ganons_Castle, 3) and
(logic_lens_castle_mq or can_use(Lens_of_Truth)) and
(Progressive_Hookshot or logic_light_trial_mq)"
},
"locations": {
"Ganons Castle MQ Light Trial Lullaby Chest": "can_play(Zeldas_Lullaby)"
}
}
]

View File

@ -3,111 +3,149 @@
"region_name": "Ganons Castle Lobby",
"dungeon": "Ganons Castle",
"exits": {
"Castle Grounds": "True",
"Castle Grounds From Ganons Castle": "True",
"Ganons Castle Forest Trial": "True",
"Ganons Castle Fire Trial": "True",
"Ganons Castle Water Trial": "True",
"Ganons Castle Shadow Trial": "True",
"Ganons Castle Spirit Trial": "True",
"Ganons Castle Fire Trial": "True",
"Ganons Castle Light Trial": "can_use(Golden_Gauntlets)",
"Ganons Castle Spirit Trial": "True",
"Ganons Castle Deku Scrubs": "logic_lens_castle or can_use(Lens_of_Truth)",
"Ganons Castle Tower": "
(skipped_trials[Forest] or 'Forest Trial Clear') and
(skipped_trials[Fire] or 'Fire Trial Clear') and
(skipped_trials[Water] or 'Water Trial Clear') and
(skipped_trials[Shadow] or 'Shadow Trial Clear') and
(skipped_trials[Spirit] or 'Spirit Trial Clear') and
(skipped_trials[Light] or 'Light Trial Clear')",
"Ganons Castle Deku Scrubs": "logic_lens_castle or can_use(Lens_of_Truth)"
}
},
{
"region_name": "Ganons Castle Deku Scrubs",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Deku Scrub Center-Left": "True",
"Ganons Castle Deku Scrub Center-Right": "True",
"Ganons Castle Deku Scrub Right": "True",
"Ganons Castle Deku Scrub Left": "True",
"Free Fairies": "has_bottle"
(skipped_trials[Light] or 'Light Trial Clear')"
}
},
{
"region_name": "Ganons Castle Forest Trial",
"dungeon": "Ganons Castle",
"events": {
"Forest Trial Clear": "can_use(Light_Arrows) and (Fire_Arrows or Dins_Fire)"
},
"locations": {
"Ganons Castle Forest Trial Chest": "True"
"Ganons Castle Forest Trial Chest": "
is_adult or Slingshot or Sticks or Kokiri_Sword or can_use(Dins_Fire)"
},
"exits": {
"Ganons Castle Forest Trial Ending": "
can_use(Fire_Arrows) or (can_use(Dins_Fire) and (can_use(Bow) or can_use(Hookshot)))"
}
},
{
"region_name": "Ganons Castle Fire Trial",
"region_name": "Ganons Castle Forest Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Fire Trial Clear": "
can_use(Goron_Tunic) and can_use(Golden_Gauntlets) and
can_use(Light_Arrows) and can_use(Longshot)"
"Forest Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Forest Trial Pot 1": "True",
"Ganons Castle Forest Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Water Trial",
"dungeon": "Ganons Castle",
"events": {
"Water Trial Clear": "Blue_Fire and Megaton_Hammer and can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Water Trial Left Chest": "True",
"Ganons Castle Water Trial Right Chest": "True",
"Fairy Pot": "Blue_Fire and has_bottle",
"Blue Fire": "has_bottle"
"Blue Fire": "
has_bottle and (is_adult or Sticks or Kokiri_Sword or has_explosives)",
"Fairy Pot": "
Blue_Fire and (is_adult or has_explosives or can_use(Dins_Fire))"
},
"exits": {
"Ganons Castle Water Trial Ending": "Blue_Fire and can_use(Megaton_Hammer)"
}
},
{
"region_name": "Ganons Castle Water Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Water Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Water Trial Pot 1": "True",
"Ganons Castle Water Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Shadow Trial",
"dungeon": "Ganons Castle",
"events": {
"Shadow Trial Clear": "
can_use(Light_Arrows) and Megaton_Hammer and
((Fire_Arrows and (logic_lens_castle or can_use(Lens_of_Truth))) or
(can_use(Longshot) and (Hover_Boots or (Dins_Fire and (logic_lens_castle or can_use(Lens_of_Truth))))))"
},
"locations": {
"Ganons Castle Shadow Trial Front Chest": "
can_use(Fire_Arrows) or Progressive_Hookshot or
Hover_Boots or can_play(Song_of_Time)",
"Ganons Castle Shadow Trial Golden Gauntlets Chest": "
can_use(Fire_Arrows) or
(can_use(Longshot) and (Hover_Boots or can_use(Dins_Fire)))"
is_child or can_use(Fire_Arrows) or Hookshot or
Hover_Boots or can_play(Song_of_Time)"
},
"exits": {
"Ganons Castle Shadow Trial First Gap": "can_use(Longshot) or can_use(Fire_Arrows)"
}
},
{
"region_name": "Ganons Castle Spirit Trial",
"region_name": "Ganons Castle Shadow Trial First Gap",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Shadow Trial Like Like Pot 1": "True",
"Ganons Castle Shadow Trial Like Like Pot 2": "True"
},
"exits": {
"Ganons Castle Shadow Trial Second Gap": "Hover_Boots or has_fire_source"
}
},
{
"region_name": "Ganons Castle Shadow Trial Second Gap",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Shadow Trial Golden Gauntlets Chest": "True",
"Ganons Castle Shadow Trial Recovery Heart 1": "
logic_lens_castle or can_use(Lens_of_Truth) or Hover_Boots",
"Ganons Castle Shadow Trial Recovery Heart 2": "
logic_lens_castle or can_use(Lens_of_Truth) or Hover_Boots",
"Ganons Castle Shadow Trial Recovery Heart 3": "
logic_lens_castle or can_use(Lens_of_Truth) or Hover_Boots"
},
"exits": {
"Ganons Castle Shadow Trial Ending": "
Megaton_Hammer and
(logic_lens_castle or can_use(Lens_of_Truth) or (Longshot and Hover_Boots))"
}
},
{
"region_name": "Ganons Castle Shadow Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Spirit Trial Clear": "
can_use(Light_Arrows) and Mirror_Shield and has_bombchus and
(logic_spirit_trial_hookshot or Progressive_Hookshot)"
"Shadow Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Spirit Trial Crystal Switch Chest": "
(logic_spirit_trial_hookshot or Progressive_Hookshot)",
"Ganons Castle Spirit Trial Invisible Chest": "
(logic_spirit_trial_hookshot or Progressive_Hookshot) and
has_bombchus and (logic_lens_castle or can_use(Lens_of_Truth))",
"Nut Pot": "
(logic_spirit_trial_hookshot or Progressive_Hookshot) and
has_bombchus and Bow and Mirror_Shield"
"Ganons Castle Shadow Trial Pot 1": "True",
"Ganons Castle Shadow Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Fire Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Fire Trial Recovery Heart": "True"
},
"exits": {
"Ganons Castle Fire Trial Ending": "
is_adult and Goron_Tunic and Golden_Gauntlets and Longshot"
}
},
{
"region_name": "Ganons Castle Fire Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Fire Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Fire Trial Pot 1": "True",
"Ganons Castle Fire Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Light Trial",
"dungeon": "Ganons Castle",
"events": {
"Light Trial Clear": "
can_use(Light_Arrows) and Progressive_Hookshot and
(Small_Key_Ganons_Castle, 2) and (logic_lens_castle or can_use(Lens_of_Truth))"
},
"locations": {
"Ganons Castle Light Trial First Left Chest": "True",
"Ganons Castle Light Trial Second Left Chest": "True",
@ -115,9 +153,88 @@
"Ganons Castle Light Trial First Right Chest": "True",
"Ganons Castle Light Trial Second Right Chest": "True",
"Ganons Castle Light Trial Third Right Chest": "True",
"Ganons Castle Light Trial Invisible Enemies Chest": "logic_lens_castle or can_use(Lens_of_Truth)",
"Ganons Castle Light Trial Invisible Enemies Chest": "
logic_lens_castle or can_use(Lens_of_Truth)",
"Ganons Castle Light Trial Lullaby Chest": "
can_play(Zeldas_Lullaby) and (Small_Key_Ganons_Castle, 1)"
(Small_Key_Ganons_Castle, 1) and can_play(Zeldas_Lullaby)"
},
"exits": {
"Ganons Castle Light Trial Boulder Room": "(Small_Key_Ganons_Castle, 2)"
}
},
{
"region_name": "Ganons Castle Light Trial Boulder Room",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Light Trial Boulder Pot": "True"
},
"exits": {
"Ganons Castle Light Trial Ending": "Hookshot and (logic_lens_castle or can_use(Lens_of_Truth))"
}
},
{
"region_name": "Ganons Castle Light Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Light Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Light Trial Pot 1": "True",
"Ganons Castle Light Trial Pot 2": "True"
}
},
{
"region_name": "Ganons Castle Spirit Trial",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Spirit Trial Recovery Heart": "True"
},
"exits": {
"Ganons Castle Spirit Trial Second Room Front": "
can_use(Hookshot) or (logic_spirit_trial_hookshot and can_jumpslash)"
}
},
{
"region_name": "Ganons Castle Spirit Trial Second Room Front",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Spirit Trial Crystal Switch Chest": "True"
},
"exits": {
"Ganons Castle Spirit Trial Second Room Back": "has_bombchus"
}
},
{
"region_name": "Ganons Castle Spirit Trial Second Room Back",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Spirit Trial Invisible Chest": "logic_lens_castle or can_use(Lens_of_Truth)"
},
"exits": {
"Ganons Castle Spirit Trial Ending": "is_adult and Bow and Mirror_Shield"
}
},
{
"region_name": "Ganons Castle Spirit Trial Ending",
"dungeon": "Ganons Castle",
"events": {
"Spirit Trial Clear": "can_use(Light_Arrows)"
},
"locations": {
"Ganons Castle Spirit Trial Pot 1": "True",
"Ganons Castle Spirit Trial Pot 2": "True",
"Nut Pot": "True"
}
},
{
"region_name": "Ganons Castle Deku Scrubs",
"dungeon": "Ganons Castle",
"locations": {
"Ganons Castle Deku Scrub Center-Left": "can_stun_deku",
"Ganons Castle Deku Scrub Center-Right": "can_stun_deku",
"Ganons Castle Deku Scrub Right": "can_stun_deku",
"Ganons Castle Deku Scrub Left": "can_stun_deku",
"Free Fairies": "has_bottle"
}
}
]

View File

@ -8,12 +8,17 @@
"Gerudo Training Ground MQ Hidden Ceiling Chest": "logic_lens_gtg_mq or can_use(Lens_of_Truth)",
"Gerudo Training Ground MQ Maze Path First Chest": "True",
"Gerudo Training Ground MQ Maze Path Second Chest": "True",
"Gerudo Training Ground MQ Maze Path Third Chest": "(Small_Key_Gerudo_Training_Ground, 1)"
"Gerudo Training Ground MQ Maze Path Third Chest": "(Small_Key_Gerudo_Training_Ground, 1)",
"Gerudo Training Ground MQ Lobby Left Pot 1": "True",
"Gerudo Training Ground MQ Lobby Left Pot 2": "True",
"Gerudo Training Ground MQ Lobby Right Pot 1": "True",
"Gerudo Training Ground MQ Lobby Right Pot 2": "True",
"Gerudo Training Ground MQ Maze Crate": "(Small_Key_Gerudo_Training_Ground, 3) and can_break_crate"
},
"exits": {
"Gerudo Fortress": "True",
"Gerudo Training Ground Left Side": "here(has_fire_source)",
"Gerudo Training Ground Right Side": "here(can_use(Bow) or can_use(Slingshot))"
"Gerudo Training Ground Right Side": "here(can_use(Bow) or can_use(Slingshot))",
"Gerudo Training Ground Left Side": "here(has_fire_source)"
}
},
{
@ -21,12 +26,12 @@
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground MQ Dinolfos Chest": "is_adult",
"Wall Fairy": "has_bottle and can_use(Bow)" #in the Dinalfos room shoot the Gerudo symbol above the door to the lava room.
# In the Dinalfos room, shoot the Gerudo symbol above the door to the lava room.
"Wall Fairy": "has_bottle and can_use(Bow)"
},
"exits": {
# Still requires has_fire_source in the room
"Gerudo Training Ground Underwater": "
(Bow or can_use(Longshot)) and can_use(Hover_Boots)"
# Fire source is checked in the water room itself.
"Gerudo Training Ground Underwater": "is_adult and (Bow or Longshot) and Hover_Boots"
}
},
{
@ -34,8 +39,8 @@
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground MQ Underwater Silver Rupee Chest": "
has_fire_source and can_use(Iron_Boots) and
(logic_fewer_tunic_requirements or can_use(Zora_Tunic)) and can_take_damage"
has_fire_source and Iron_Boots and
(logic_fewer_tunic_requirements or Zora_Tunic) and can_take_damage"
}
},
{
@ -62,20 +67,23 @@
"exits": {
"Gerudo Training Ground Back Areas": "
is_adult and (logic_lens_gtg_mq or can_use(Lens_of_Truth)) and Blue_Fire and
(can_play(Song_of_Time) or (logic_gtg_fake_wall and can_use(Hover_Boots)))"
(can_play(Song_of_Time) or (logic_gtg_fake_wall and Hover_Boots))"
}
},
{
"region_name": "Gerudo Training Ground Back Areas",
"dungeon": "Gerudo Training Ground",
"locations": {
# The switch that opens the door to the Ice Arrows chest can be hit with a precise jumpslash.
"Gerudo Training Ground MQ Ice Arrows Chest": "
(Small_Key_Gerudo_Training_Ground, 3) and Megaton_Hammer",
"Gerudo Training Ground MQ Eye Statue Chest": "Bow",
"Gerudo Training Ground MQ Second Iron Knuckle Chest": "True",
"Gerudo Training Ground MQ Flame Circle Chest": "can_use(Hookshot) or Bow or has_explosives"
"Gerudo Training Ground MQ Flame Circle Chest": "Hookshot or Bow or has_explosives"
},
"exits": {
"Gerudo Training Ground Central Maze Right": "Megaton_Hammer",
"Gerudo Training Ground Right Side": "can_use(Longshot)"
"Gerudo Training Ground Right Side": "Longshot"
}
},
{
@ -83,16 +91,11 @@
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground MQ Maze Right Central Chest": "True",
"Gerudo Training Ground MQ Maze Right Side Chest": "True",
# The switch that opens the door to the Ice Arrows chest can be hit with a precise jumpslash.
"Gerudo Training Ground MQ Ice Arrows Chest": "
(Small_Key_Gerudo_Training_Ground, 3)"
"Gerudo Training Ground MQ Maze Right Side Chest": "True"
},
"exits": {
# guarantees fire with torch
"Gerudo Training Ground Underwater": "
can_use(Longshot) or (can_use(Hookshot) and Bow)",
"Gerudo Training Ground Right Side": "can_use(Hookshot)"
"Gerudo Training Ground Underwater": "Longshot or (Hookshot and Bow)",
"Gerudo Training Ground Right Side": "Hookshot"
}
}
]

View File

@ -7,30 +7,39 @@
"Gerudo Training Ground Lobby Right Chest": "can_use(Bow) or can_use(Slingshot)",
"Gerudo Training Ground Stalfos Chest": "is_adult or Kokiri_Sword",
"Gerudo Training Ground Beamos Chest": "has_explosives and (is_adult or Kokiri_Sword)",
"Wall Fairy": "has_bottle and can_use(Bow)" #in the Beamos room shoot the Gerudo symbol above the door to the lava room.
},
"exits": {
"Gerudo Fortress": "True",
"Gerudo Training Ground Heavy Block Room": "
(is_adult or Kokiri_Sword) and
(can_use(Hookshot) or logic_gtg_without_hookshot)",
"Gerudo Training Ground Lava Room": "
here(has_explosives and (is_adult or Kokiri_Sword))",
"Gerudo Training Ground Central Maze": "True"
}
},
{
"region_name": "Gerudo Training Ground Central Maze",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Hidden Ceiling Chest": "(Small_Key_Gerudo_Training_Ground, 3) and (logic_lens_gtg or can_use(Lens_of_Truth))",
"Gerudo Training Ground Hidden Ceiling Chest": "
(Small_Key_Gerudo_Training_Ground, 3) and (logic_lens_gtg or can_use(Lens_of_Truth))",
"Gerudo Training Ground Maze Path First Chest": "(Small_Key_Gerudo_Training_Ground, 4)",
"Gerudo Training Ground Maze Path Second Chest": "(Small_Key_Gerudo_Training_Ground, 6)",
"Gerudo Training Ground Maze Path Third Chest": "(Small_Key_Gerudo_Training_Ground, 7)",
"Gerudo Training Ground Maze Path Final Chest": "(Small_Key_Gerudo_Training_Ground, 9)"
"Gerudo Training Ground Maze Path Final Chest": "(Small_Key_Gerudo_Training_Ground, 9)",
"Gerudo Training Ground Beamos Recovery Heart 1": "True",
"Gerudo Training Ground Beamos Recovery Heart 2": "True",
# In the Beamos room, shoot the Gerudo symbol above the door to the lava room.
"Wall Fairy": "has_bottle and can_use(Bow)"
},
"exits": {
"Gerudo Training Ground Central Maze Right": "(Small_Key_Gerudo_Training_Ground, 9)"
"Gerudo Fortress": "True",
"Gerudo Training Ground Lava Room": "
here(has_explosives and (is_adult or Kokiri_Sword))",
"Gerudo Training Ground Central Maze Right": "(Small_Key_Gerudo_Training_Ground, 9)",
"Gerudo Training Ground Heavy Block Room": "
(is_adult or Kokiri_Sword) and
(can_use(Hookshot) or logic_gtg_without_hookshot)"
}
},
{
"region_name": "Gerudo Training Ground Lava Room",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Underwater Silver Rupee Chest": "
is_adult and Hookshot and can_play(Song_of_Time) and
Iron_Boots and (logic_fewer_tunic_requirements or Zora_Tunic)"
},
"exits": {
"Gerudo Training Ground Central Maze Right": "can_play(Song_of_Time) or is_child",
"Gerudo Training Ground Hammer Room": "
is_adult and (Longshot or (Hookshot and Hover_Boots))"
}
},
{
@ -42,54 +51,8 @@
"Gerudo Training Ground Freestanding Key": "True"
},
"exits": {
"Gerudo Training Ground Hammer Room": "can_use(Hookshot)",
"Gerudo Training Ground Lava Room": "True"
}
},
{
"region_name": "Gerudo Training Ground Lava Room",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Underwater Silver Rupee Chest": "
can_use(Hookshot) and can_play(Song_of_Time) and Iron_Boots and
(logic_fewer_tunic_requirements or can_use(Zora_Tunic))"
},
"exits": {
"Gerudo Training Ground Central Maze Right": "can_play(Song_of_Time) or is_child",
"Gerudo Training Ground Hammer Room": "
can_use(Longshot) or (can_use(Hookshot) and can_use(Hover_Boots))"
}
},
{
"region_name": "Gerudo Training Ground Hammer Room",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Hammer Room Clear Chest": "True",
"Gerudo Training Ground Hammer Room Switch Chest": "can_use(Megaton_Hammer)"
},
"exits": {
"Gerudo Training Ground Eye Statue Lower": "can_use(Megaton_Hammer) and Bow",
"Gerudo Training Ground Lava Room": "True"
}
},
{
"region_name": "Gerudo Training Ground Eye Statue Lower",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Eye Statue Chest": "can_use(Bow)"
},
"exits": {
"Gerudo Training Ground Hammer Room": "True"
}
},
{
"region_name": "Gerudo Training Ground Eye Statue Upper",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Near Scarecrow Chest": "can_use(Bow)"
},
"exits": {
"Gerudo Training Ground Eye Statue Lower": "True"
"Gerudo Training Ground Lava Room": "True",
"Gerudo Training Ground Hammer Room": "can_use(Hookshot)"
}
},
{
@ -100,11 +63,19 @@
},
"exits": {
"Gerudo Training Ground Eye Statue Upper": "
(logic_lens_gtg or can_use(Lens_of_Truth)) and
(can_use(Hookshot) or (logic_gtg_fake_wall and can_use(Hover_Boots)))",
"Gerudo Training Ground Like Like Room": "
can_use(Silver_Gauntlets) and (logic_lens_gtg or can_use(Lens_of_Truth)) and
(can_use(Hookshot) or (logic_gtg_fake_wall and can_use(Hover_Boots)))"
is_adult and (logic_lens_gtg or can_use(Lens_of_Truth)) and
(Hookshot or (logic_gtg_fake_wall and Hover_Boots))"
}
},
{
"region_name": "Gerudo Training Ground Eye Statue Upper",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Near Scarecrow Chest": "Bow"
},
"exits": {
"Gerudo Training Ground Like Like Room": "Silver_Gauntlets",
"Gerudo Training Ground Eye Statue Lower": "True"
}
},
{
@ -116,5 +87,27 @@
"Gerudo Training Ground Heavy Block Third Chest": "True",
"Gerudo Training Ground Heavy Block Fourth Chest": "True"
}
},
{
"region_name": "Gerudo Training Ground Eye Statue Lower",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Eye Statue Chest": "Bow"
},
"exits": {
"Gerudo Training Ground Hammer Room": "True"
}
},
{
"region_name": "Gerudo Training Ground Hammer Room",
"dungeon": "Gerudo Training Ground",
"locations": {
"Gerudo Training Ground Hammer Room Clear Chest": "True",
"Gerudo Training Ground Hammer Room Switch Chest": "Megaton_Hammer"
},
"exits": {
"Gerudo Training Ground Lava Room": "True",
"Gerudo Training Ground Eye Statue Lower": "Megaton_Hammer and Bow"
}
}
]

View File

@ -3,6 +3,12 @@
"region_name": "Ice Cavern Beginning",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern MQ First Hall Pot": "True",
"Ice Cavern MQ Tektite Room Pot 1": "True",
"Ice Cavern MQ Tektite Room Pot 2": "True",
# The crystal switch in the tektite room can be hit with the pot in the first hall.
"Ice Cavern MQ Center Room Pot 1": "True",
"Ice Cavern MQ Center Room Pot 2": "True",
"Fairy Pot": "has_bottle"
},
"exits": {
@ -24,25 +30,28 @@
"Blue Fire": "has_bottle"
}
},
{
"region_name": "Ice Cavern Iron Boots Region",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern MQ Iron Boots Chest": "is_adult",
"Sheik in Ice Cavern": "is_adult",
"Ice Cavern MQ GS Ice Block": "is_adult or can_child_attack",
"Ice Cavern MQ GS Scarecrow": "
can_use(Scarecrow) or (Hover_Boots and can_use(Longshot)) or
(logic_ice_mq_scarecrow and is_adult)"
}
},
{
"region_name": "Ice Cavern Compass Room",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern MQ Compass Chest": "True",
"Ice Cavern MQ Freestanding PoH": "has_explosives",
"Ice Cavern MQ Compass Room Pot 1": "True",
"Ice Cavern MQ Compass Room Pot 2": "True",
"Ice Cavern MQ GS Red Ice": "can_play(Song_of_Time) or logic_ice_mq_red_ice_gs"
}
},
{
"region_name": "Ice Cavern Iron Boots Region",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern MQ Iron Boots Chest": "is_adult",
"Sheik in Ice Cavern": "is_adult",
"Ice Cavern MQ Near End Pot": "is_adult",
"Ice Cavern MQ GS Ice Block": "is_adult or can_child_attack",
"Ice Cavern MQ GS Scarecrow": "
can_use(Scarecrow) or (Hover_Boots and can_use(Longshot)) or
(logic_ice_mq_scarecrow and is_adult)"
}
}
]

View File

@ -2,34 +2,63 @@
{
"region_name": "Ice Cavern Beginning",
"dungeon": "Ice Cavern",
"locations":{
"Ice Cavern Frozen Blue Rupee": "Blue_Fire"
},
"exits": {
"ZF Ice Ledge": "True",
#Frezzards are weird, they are immune to KS completely. Leave sticks out as 8/10 is a lot
"Ice Cavern": "here(is_adult or has_explosives or can_use(Dins_Fire))"
# Freezards are immune to Kokiri Sword. It would take a lot of sticks.
"Ice Cavern Spinning Blades": "here(is_adult or has_explosives or can_use(Dins_Fire))"
}
},
{
"region_name": "Ice Cavern",
"region_name": "Ice Cavern Spinning Blades",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern Map Chest": "Blue_Fire and is_adult",
"Ice Cavern Compass Chest": "Blue_Fire",
"Ice Cavern Hall Pot 1": "True",
"Ice Cavern Hall Pot 2": "True",
"Ice Cavern Spinning Blade Pot 1": "True",
"Ice Cavern Spinning Blade Pot 2": "True",
"Ice Cavern Spinning Blade Pot 3": "True",
"Ice Cavern Spinning Blade Flying Pot": "True",
"Ice Cavern GS Spinning Scythe Room": "can_use(Hookshot) or can_use(Boomerang)"
},
"exits": {
"Ice Cavern Map Room": "is_adult",
"Ice Cavern Behind Ice Walls": "here(Blue_Fire)"
}
},
{
"region_name": "Ice Cavern Map Room",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern Map Chest": "Blue_Fire",
"Ice Cavern Map Room Recovery Heart 1": "True",
"Ice Cavern Map Room Recovery Heart 2": "True",
"Ice Cavern Map Room Recovery Heart 3": "True",
"Ice Cavern Frozen Pot": "Blue_Fire",
"Blue Fire": "has_bottle"
}
},
{
"region_name": "Ice Cavern Behind Ice Walls",
"dungeon": "Ice Cavern",
"locations": {
"Ice Cavern Compass Chest": "True",
"Ice Cavern Freestanding PoH": "True",
"Ice Cavern Iron Boots Chest": "
Blue_Fire and
(is_adult or Slingshot or Sticks or
Kokiri_Sword or can_use(Dins_Fire))",
is_adult or Slingshot or Sticks or Kokiri_Sword or can_use(Dins_Fire)",
"Sheik in Ice Cavern": "
Blue_Fire and
(is_adult or Slingshot or Sticks or
Kokiri_Sword or can_use(Dins_Fire))",
"Ice Cavern Freestanding PoH": "Blue_Fire",
"Ice Cavern GS Spinning Scythe Room": "can_use(Hookshot) or can_use(Boomerang)",
"Ice Cavern GS Heart Piece Room": "
Blue_Fire and (can_use(Hookshot) or can_use(Boomerang))",
is_adult or Slingshot or Sticks or Kokiri_Sword or can_use(Dins_Fire)",
"Ice Cavern Block Room Red Rupee 1": "can_play(Song_of_Time) or can_use(Boomerang)",
"Ice Cavern Block Room Red Rupee 2": "can_play(Song_of_Time) or can_use(Boomerang)",
"Ice Cavern Block Room Red Rupee 3": "can_play(Song_of_Time) or can_use(Boomerang)",
"Ice Cavern Near End Pot 1": "True",
"Ice Cavern Near End Pot 2": "True",
"Ice Cavern GS Heart Piece Room": "can_use(Hookshot) or can_use(Boomerang)",
"Ice Cavern GS Push Block Room": "
Blue_Fire and (can_use(Hookshot) or can_use(Boomerang) or
(logic_ice_block_gs and can_use(Hover_Boots)))",
"Blue Fire": "is_adult and has_bottle"
can_use(Hookshot) or can_use(Boomerang) or
(logic_ice_block_gs and can_use(Hover_Boots))"
}
}
]

View File

@ -3,64 +3,114 @@
"region_name": "Jabu Jabus Belly Beginning",
"dungeon": "Jabu Jabus Belly",
"locations": {
"Nut Pot": "True",
"Jabu Jabus Belly MQ Map Chest": "can_blast_or_smash",
"Jabu Jabus Belly MQ First Room Side Chest": "can_use(Slingshot)"
"Jabu Jabus Belly MQ First Room Side Chest": "can_use(Slingshot)",
"Jabu Jabus Belly MQ First Room Pot 1": "True",
"Jabu Jabus Belly MQ First Room Pot 2": "True",
"Nut Pot": "True"
},
"exits": {
"Zoras Fountain": "True",
"Jabu Jabus Belly Main": "here(is_child and can_use(Slingshot))"
"Jabu Jabus Belly Elevator Room": "here(can_use(Slingshot)) or jabu_shortcuts"
}
},
{
"region_name": "Jabu Jabus Belly Elevator Room",
"dungeon": "Jabu Jabus Belly",
"locations": {
"Jabu Jabus Belly MQ Second Room Lower Chest": "True",
"Jabu Jabus Belly MQ Second Room Upper Chest": "
here(can_use(Slingshot)) and
(can_use(Hover_Boots) or can_use(Hookshot) or
'Jabu Jabus Belly Floor Lowered' or jabu_shortcuts)",
"Jabu Jabus Belly MQ Compass Chest": "
(is_child or can_dive or Iron_Boots or logic_jabu_alcove_jump_dive) and
(can_use(Slingshot) or has_bombchus or can_use(Bow) or can_use(Hookshot) or
(logic_jabu_mq_rang_jump and can_use(Boomerang)))",
"Jabu Jabus Belly MQ Recovery Heart 1": "True",
"Jabu Jabus Belly MQ Recovery Heart 2": "True",
"Jabu Jabus Belly MQ Underwater Green Rupee 1": "
can_use(Boomerang) or (Progressive_Scale, 2) or can_use(Iron_Boots)",
"Jabu Jabus Belly MQ Underwater Green Rupee 2": "
can_use(Boomerang) or can_dive or can_use(Iron_Boots)",
"Jabu Jabus Belly MQ Underwater Green Rupee 3": "True",
"Jabu Jabus Belly MQ Elevator Room Pot 1": "True",
"Jabu Jabus Belly MQ Elevator Room Pot 2": "True"
},
"exits": {
"Jabu Jabus Belly Main": "
here(is_child or can_dive or Iron_Boots or logic_jabu_alcove_jump_dive)",
"Jabu Jabus Belly Before Boss": "
jabu_shortcuts or 'Jabu Jabus Belly Floor Lowered' or
('Jabu Jabus Belly Parasitic Tentacle Cleared' and
(can_use(Hover_Boots) or can_use(Hookshot)))"
}
},
{
"region_name": "Jabu Jabus Belly Main",
"dungeon": "Jabu Jabus Belly",
"locations": {
"Jabu Jabus Belly MQ Second Room Lower Chest": "True",
"Jabu Jabus Belly MQ Second Room Upper Chest": "
can_use(Hover_Boots) or can_use(Hookshot) or
at('Jabu Jabus Belly Boss Area', is_child)",
"Jabu Jabus Belly MQ Compass Chest": "True",
"Jabu Jabus Belly MQ Basement Near Vines Chest": "True",
"Jabu Jabus Belly MQ Basement Near Switches Chest": "True",
"Jabu Jabus Belly MQ Basement Near Vines Chest": "can_use(Slingshot)",
"Jabu Jabus Belly MQ Basement Near Switches Chest": "can_use(Slingshot)",
"Jabu Jabus Belly MQ Boomerang Room Small Chest": "True",
"Jabu Jabus Belly MQ Boomerang Chest": "True",
"Jabu Jabus Belly MQ Boomerang Chest": "
Kokiri_Sword or Slingshot or Bombs or Sticks or is_adult",
"Jabu Jabus Belly MQ Boomerang Room Pot 1": "True",
"Jabu Jabus Belly MQ Boomerang Room Pot 2": "True",
"Jabu Jabus Belly MQ GS Boomerang Chest Room": "
can_play(Song_of_Time) or (logic_jabu_mq_sot_gs and can_use(Boomerang))"
(can_play(Song_of_Time) and (can_child_attack or is_adult)) or
(logic_jabu_mq_sot_gs and can_use(Boomerang))",
"Jabu Jabus Belly MQ GS Invisible Enemies Room": "
(at('Jabu Jabus Belly Depths', True) or jabu_shortcuts) and
((can_use(Hookshot) and can_use(Hover_Boots)) or
(here((logic_lens_jabu_mq or can_use(Lens_of_Truth)) and
(can_use(Slingshot) or can_use(Bow) or can_use(Longshot) or
(can_use(Hookshot) and can_use(Iron_Boots) and logic_lens_jabu_mq))) and
(can_use(Boomerang) or (can_use(Hookshot) and can_use(Iron_Boots)))))"
# Lens of Truth cannot be used underwater.
# Adult's legs are too long to swim directly onto the Hookshot pillar.
},
"exits": {
"Jabu Jabus Belly Beginning": "True",
"Jabu Jabus Belly Depths": "has_explosives and can_use(Boomerang)"
"Jabu Jabus Belly Depths": "has_explosives and can_use(Boomerang) and can_use(Slingshot)"
}
},
{
"region_name": "Jabu Jabus Belly Depths",
"dungeon": "Jabu Jabus Belly",
"events": {
"Jabu Jabus Belly Parasitic Tentacle Cleared": "True"
},
"locations": {
"Jabu Jabus Belly MQ Falling Like Like Room Chest": "True",
"Jabu Jabus Belly MQ GS Tailpasaran Room": "Sticks or can_use(Dins_Fire)",
"Jabu Jabus Belly MQ GS Invisible Enemies Room": "
(logic_lens_jabu_mq or can_use(Lens_of_Truth)) or
at('Jabu Jabus Belly Main', can_use(Hover_Boots) and can_use(Hookshot))"
"Jabu Jabus Belly MQ Falling Like Like Room Pot 1": "True",
"Jabu Jabus Belly MQ Falling Like Like Room Pot 2": "True",
"Jabu Jabus Belly MQ GS Tailpasaran Room": "Sticks or can_use(Dins_Fire)"
},
"exits": {
"Jabu Jabus Belly Main": "True",
"Jabu Jabus Belly Boss Area": "Sticks or (can_use(Dins_Fire) and Kokiri_Sword)"
"Jabu Jabus Belly Past Big Octo": "Sticks or (can_use(Dins_Fire) and Kokiri_Sword)"
}
},
{
"region_name": "Jabu Jabus Belly Boss Area",
"region_name": "Jabu Jabus Belly Past Big Octo",
"dungeon": "Jabu Jabus Belly",
"events": {
"Jabu Jabus Belly Floor Lowered": "True"
},
"locations": {
"Jabu Jabus Belly MQ Cow": "can_play(Eponas_Song)"
}
},
{
"region_name": "Jabu Jabus Belly Before Boss",
"dungeon": "Jabu Jabus Belly",
"locations": {
"Jabu Jabus Belly MQ Cow" : "can_play(Eponas_Song)",
"Jabu Jabus Belly MQ Near Boss Chest": "True",
"Jabu Jabus Belly Barinade Heart": "True",
"Barinade": "True",
"Jabu Jabus Belly MQ GS Near Boss": "True",
"Jabu Jabus Belly MQ Near Boss Chest": "can_use(Slingshot)",
"Jabu Jabus Belly MQ GS Near Boss": "
can_use(Boomerang) or (logic_jabu_near_boss_ranged and can_use(Hookshot))",
"Fairy Pot": "has_bottle"
},
"exits": {
"Jabu Jabus Belly Main": "True"
"Jabu Jabus Belly Boss Door": "here(can_use(Slingshot)) or jabu_shortcuts"
}
}
]

View File

@ -12,17 +12,25 @@
"dungeon": "Jabu Jabus Belly",
"locations": {
"Jabu Jabus Belly Boomerang Chest": "True",
"Jabu Jabus Belly Deku Scrub": "
can_dive or is_child or logic_jabu_alcove_jump_dive or can_use(Iron_Boots)",
"Jabu Jabus Belly Small Wooden Crate": "True",
"Jabu Jabus Belly Basement 2 Octoroks Pot 1": "can_use(Boomerang) or can_use(Hover_Boots)",
"Jabu Jabus Belly Basement 2 Octoroks Pot 2": "can_use(Boomerang) or can_use(Hover_Boots)",
"Jabu Jabus Belly Basement 2 Octoroks Pot 3": "can_use(Boomerang) or can_use(Hover_Boots)",
"Jabu Jabus Belly Basement 2 Octoroks Pot 4": "can_use(Boomerang) or can_use(Hover_Boots)",
"Jabu Jabus Belly Basement Switch Room Pot 1": "True",
"Jabu Jabus Belly Basement Switch Room Pot 2": "True",
"Jabu Jabus Belly GS Water Switch Room": "True",
"Jabu Jabus Belly GS Lobby Basement Lower": "can_use(Boomerang) or can_use(Hookshot)",
"Jabu Jabus Belly GS Lobby Basement Upper": "can_use(Boomerang) or can_use(Hookshot)",
"Jabu Jabus Belly Deku Scrub": "
can_dive or is_child or logic_jabu_scrub_jump_dive or can_use(Iron_Boots)",
"Fairy Pot": "has_bottle"
},
"exits": {
"Jabu Jabus Belly Beginning": "True",
"Jabu Jabus Belly Depths": "can_use(Boomerang)",
"Jabu Jabus Belly Boss Area": "logic_jabu_boss_gs_adult and can_use(Hover_Boots)"
"Jabu Jabus Belly Before Boss": "
(logic_jabu_boss_hover and can_use(Hover_Boots))
or jabu_shortcuts or 'Jabu Jabus Belly Floor Lowered'"
}
},
{
@ -33,21 +41,34 @@
"Jabu Jabus Belly Compass Chest": "True"
},
"exits": {
"Jabu Jabus Belly Main": "True",
"Jabu Jabus Belly Boss Area": "Sticks or Kokiri_Sword"
"Jabu Jabus Belly Past Big Octo": "Sticks or Kokiri_Sword"
}
},
{
"region_name": "Jabu Jabus Belly Boss Area",
"region_name": "Jabu Jabus Belly Past Big Octo",
"dungeon": "Jabu Jabus Belly",
"events": {
"Jabu Jabus Belly Floor Lowered": "True"
},
"locations": {
"Jabu Jabus Belly Above Big Octo Pot 1": "True",
"Jabu Jabus Belly Above Big Octo Pot 2": "True",
"Nut Pot": "True"
}
},
{
"region_name": "Jabu Jabus Belly Before Boss",
"dungeon": "Jabu Jabus Belly",
"locations": {
"Jabu Jabus Belly Barinade Heart": "can_use(Boomerang)",
"Barinade": "can_use(Boomerang)",
"Jabu Jabus Belly GS Near Boss": "True",
"Nut Pot": "True"
"Jabu Jabus Belly GS Near Boss": "True"
},
"exits": {
"Jabu Jabus Belly Main": "True"
"Jabu Jabus Belly Boss Door": "
can_use(Boomerang) or
(logic_jabu_near_boss_ranged and
(can_use(Hookshot) or can_use(Bow) or can_use(Slingshot))) or
(logic_jabu_near_boss_explosives and
(has_bombchus or (Bombs and can_use(Hover_Boots))))"
}
}
]

File diff suppressed because it is too large Load Diff

View File

@ -12,11 +12,16 @@
{
"region_name": "Shadow Temple Beginning",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Truth Spinner Small Wooden Crate 1": "True",
"Shadow Temple MQ Truth Spinner Small Wooden Crate 2": "True",
"Shadow Temple MQ Truth Spinner Small Wooden Crate 3": "True",
"Shadow Temple MQ Truth Spinner Small Wooden Crate 4": "True"
},
"exits": {
"Shadow Temple Entryway": "True",
"Shadow Temple First Beamos": "
can_use(Fire_Arrows) or Hover_Boots or
(logic_shadow_mq_gap and can_use(Longshot))",
shadow_temple_shortcuts or can_use(Fire_Arrows) or Hover_Boots or
(logic_shadow_mq_gap and Longshot)",
"Shadow Temple Dead Hand Area": "has_explosives and (Small_Key_Shadow_Temple, 6)"
}
},
@ -25,7 +30,15 @@
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Compass Chest": "True",
"Shadow Temple MQ Hover Boots Chest": "can_play(Song_of_Time) and Bow"
"Shadow Temple MQ Hover Boots Chest": "can_play(Song_of_Time) and Bow",
"Shadow Temple MQ Whispering Walls Pot 1": "True",
"Shadow Temple MQ Whispering Walls Pot 2": "True",
"Shadow Temple MQ Compass Room Pot 1": "True",
"Shadow Temple MQ Compass Room Pot 2": "True",
"Shadow Temple MQ Whispering Walls Before Time Block Flying Pot 1": "True",
"Shadow Temple MQ Whispering Walls Before Time Block Flying Pot 2": "True",
"Shadow Temple MQ Whispering Walls After Time Block Flying Pot 1": "can_play(Song_of_Time)",
"Shadow Temple MQ Whispering Walls After Time Block Flying Pot 2": "can_play(Song_of_Time)"
}
},
{
@ -36,48 +49,91 @@
"Shadow Temple MQ Early Gibdos Chest": "True",
"Shadow Temple MQ Near Ship Invisible Chest": "True"
},
# When shadow shortcuts are on, the central areas of the dungeon will require all 6 keys to
# access. However, the final locked door does not actually prevent you from reaching any area
# since all opening it does is complete the loop through the dungeon. We can take advantage of
# this to reduce the key requirement to 5 by confirming we have the items to reach the check
# regardless of which door is unlocked into any given room. An exception can be made for using
# the Longshot to get from the lower door of huge pit room up to the invisible blades room.
# Since Longshot is required to use the final key on the door to the BK chest room, you must
# either have Longshot or be unable to spend more than 5 keys.
"exits": {
"Shadow Temple Upper Huge Pit": "has_explosives and (Small_Key_Shadow_Temple, 2)"
"Shadow Temple Upper Huge Pit": "
has_explosives and
(((Small_Key_Shadow_Temple, 2) and not shadow_temple_shortcuts) or
(Small_Key_Shadow_Temple, 5))",
"Shadow Temple Boat": "shadow_temple_shortcuts"
}
},
{
"region_name": "Shadow Temple Upper Huge Pit",
"dungeon": "Shadow Temple",
"exits": {
"Shadow Temple Invisible Blades": "
(not shadow_temple_shortcuts or (Small_Key_Shadow_Temple, 6) or
((logic_lens_shadow_mq_platform or can_use(Lens_of_Truth)) and Hover_Boots)) and
(can_play(Song_of_Time) or
(logic_shadow_mq_invisible_blades and damage_multiplier != 'ohko'))",
"Shadow Temple Lower Huge Pit": "has_fire_source or logic_shadow_mq_huge_pit"
}
},
{
"region_name": "Shadow Temple Invisible Blades",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Invisible Blades Visible Chest": "
can_play(Song_of_Time) or
(logic_shadow_mq_invisible_blades and damage_multiplier != 'ohko')",
logic_lens_shadow_mq_invisible_blades or can_use(Lens_of_Truth) or can_use(Nayrus_Love)",
"Shadow Temple MQ Invisible Blades Invisible Chest": "
can_play(Song_of_Time) or
(logic_shadow_mq_invisible_blades and damage_multiplier != 'ohko')"
},
"exits": {
"Shadow Temple Lower Huge Pit": "has_fire_source or logic_shadow_mq_huge_pit"
logic_lens_shadow_mq_invisible_blades or can_use(Lens_of_Truth) or can_use(Nayrus_Love)",
"Shadow Temple MQ Invisible Blades Recovery Heart 1": "True",
"Shadow Temple MQ Invisible Blades Recovery Heart 2": "True"
}
},
{
"region_name": "Shadow Temple Lower Huge Pit",
"dungeon": "Shadow Temple",
"exits": {
"Shadow Temple Falling Spikes": "
not shadow_temple_shortcuts or (Small_Key_Shadow_Temple, 6) or
((logic_lens_shadow_mq_platform or can_use(Lens_of_Truth)) and Hover_Boots and
(has_fire_source or logic_shadow_mq_huge_pit))",
"Shadow Temple Invisible Spikes": "
(logic_lens_shadow_mq_platform or can_use(Lens_of_Truth)) and
Hover_Boots and (Small_Key_Shadow_Temple, 3)",
"Shadow Temple Upper Huge Pit": "Longshot"
}
},
{
"region_name": "Shadow Temple Falling Spikes",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Beamos Silver Rupees Chest": "can_use(Longshot)",
"Shadow Temple MQ Beamos Silver Rupees Chest": "Longshot",
"Shadow Temple MQ Falling Spikes Lower Chest": "True",
"Shadow Temple MQ Falling Spikes Upper Chest": "
(logic_shadow_umbrella and Hover_Boots) or Progressive_Strength_Upgrade",
"Shadow Temple MQ Falling Spikes Switch Chest": "
(logic_shadow_umbrella and Hover_Boots) or Progressive_Strength_Upgrade",
"Shadow Temple MQ Invisible Spikes Chest": "
Hover_Boots and (Small_Key_Shadow_Temple, 3) and
(logic_lens_shadow_mq_back or can_use(Lens_of_Truth))",
"Shadow Temple MQ Stalfos Room Chest": "
Hover_Boots and (Small_Key_Shadow_Temple, 3) and Progressive_Hookshot and
(logic_lens_shadow_mq_back or can_use(Lens_of_Truth))",
"Shadow Temple MQ Falling Spikes Lower Pot 1": "True",
"Shadow Temple MQ Falling Spikes Lower Pot 2": "True",
"Shadow Temple MQ Falling Spikes Upper Pot 1": "
(logic_shadow_umbrella and Hover_Boots) or Progressive_Strength_Upgrade",
"Shadow Temple MQ Falling Spikes Upper Pot 2": "
(logic_shadow_umbrella and Hover_Boots) or Progressive_Strength_Upgrade",
"Shadow Temple MQ GS Falling Spikes Room": "
(logic_shadow_umbrella_gs and Hover_Boots) or Progressive_Hookshot"
(logic_shadow_umbrella_gs and Hover_Boots) or Hookshot"
}
},
{
"region_name": "Shadow Temple Invisible Spikes",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Invisible Spikes Chest": "True",
"Shadow Temple MQ Stalfos Room Chest": "Hookshot"
},
"exits": {
"Shadow Temple Wind Tunnel": "
Hover_Boots and (logic_lens_shadow_mq_back or can_use(Lens_of_Truth)) and
Progressive_Hookshot and (Small_Key_Shadow_Temple, 4)"
"Shadow Temple Wind Tunnel": "Hookshot and (Small_Key_Shadow_Temple, 4)",
"Shadow Temple Lower Huge Pit": "
(logic_lens_shadow_mq_platform or can_use(Lens_of_Truth)) and Hover_Boots"
}
},
{
@ -85,43 +141,113 @@
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Wind Hint Chest": "True",
"Shadow Temple MQ GS Wind Hint Room": "Hookshot"
},
"exits": {
"Shadow Temple After Wind": "True",
"Shadow Temple Invisible Spikes": "Hookshot"
}
},
{
"region_name": "Shadow Temple After Wind",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ After Wind Enemy Chest": "True",
"Shadow Temple MQ After Wind Hidden Chest": "True",
"Shadow Temple MQ GS Wind Hint Room": "True",
"Shadow Temple MQ After Wind Hidden Chest": "has_explosives",
"Shadow Temple MQ After Wind Pot 1": "True",
"Shadow Temple MQ After Wind Pot 2": "True",
"Shadow Temple MQ After Wind Flying Pot 1": "True",
"Shadow Temple MQ After Wind Flying Pot 2": "True",
"Shadow Temple MQ GS After Wind": "True",
"Nut Pot": "True"
},
"exits": {
"Shadow Temple Beyond Boat": "
can_play(Zeldas_Lullaby) and (Small_Key_Shadow_Temple, 5)"
"Shadow Temple Boat": "(Small_Key_Shadow_Temple, 5)",
"Shadow Temple Wind Tunnel": "Hover_Boots or logic_shadow_mq_windy_walkway"
}
},
{
"region_name": "Shadow Temple Boat",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Before Boat Recovery Heart 1": "can_use(Distant_Scarecrow)",
"Shadow Temple MQ Before Boat Recovery Heart 2": "can_use(Distant_Scarecrow)"
},
"exits": {
"Shadow Temple After Wind": "(Small_Key_Shadow_Temple, 5)",
"Shadow Temple Beyond Boat": "can_play(Zeldas_Lullaby)"
}
},
{
"region_name": "Shadow Temple Beyond Boat",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Bongo Bongo Heart": "
(Bow or (logic_shadow_statue and has_bombchus)) and Boss_Key_Shadow_Temple",
"Bongo Bongo": "
(Bow or (logic_shadow_statue and has_bombchus)) and Boss_Key_Shadow_Temple",
"Shadow Temple MQ GS After Ship": "True",
"Shadow Temple MQ GS Near Boss": "Bow or (logic_shadow_statue and has_bombchus)"
"Shadow Temple MQ After Boat Pot 1": "True",
"Shadow Temple MQ After Boat Pot 2": "True",
"Shadow Temple MQ GS After Ship": "Hookshot"
},
"exits": {
"Shadow Temple Invisible Maze": "
Bow and can_play(Song_of_Time) and can_use(Longshot)"
"Shadow Temple Across Chasm": "
Bow or (logic_shadow_statue and has_bombchus) or shadow_temple_shortcuts"
}
},
{
"region_name": "Shadow Temple Across Chasm",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ After Boat Lower Recovery Heart": "True",
"Shadow Temple MQ Near Boss Pot 1": "True",
"Shadow Temple MQ Near Boss Pot 2": "True"
},
"exits": {
"Shadow Temple Invisible Maze": "Bow and can_play(Song_of_Time) and Longshot",
"Shadow Temple Before Boss": "Hover_Boots"
}
},
{
"region_name": "Shadow Temple Invisible Maze",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ Bomb Flower Chest": "
logic_lens_shadow_mq_dead_hand or can_use(Lens_of_Truth)",
"Shadow Temple MQ Freestanding Key": "True",
"Shadow Temple MQ Spike Walls Left Chest": "
can_use(Dins_Fire) and (Small_Key_Shadow_Temple, 6)",
(Small_Key_Shadow_Temple, 6) and can_use(Dins_Fire)",
"Shadow Temple MQ Boss Key Chest": "
can_use(Dins_Fire) and (Small_Key_Shadow_Temple, 6)",
"Shadow Temple MQ Bomb Flower Chest": "True",
"Shadow Temple MQ Freestanding Key": "True"
(Small_Key_Shadow_Temple, 6) and can_use(Dins_Fire)",
"Shadow Temple MQ After Boat Upper Recovery Heart 1": "True",
"Shadow Temple MQ After Boat Upper Recovery Heart 2": "True",
"Shadow Temple MQ Bomb Flower Room Pot 1": "True",
"Shadow Temple MQ Bomb Flower Room Pot 2": "True",
"Shadow Temple MQ Spike Walls Pot": "(Small_Key_Shadow_Temple, 6)"
},
"exits": {
"Shadow Temple 3 Spinning Pots Rupees": "Bombs or Progressive_Strength_Upgrade"
}
},
{
"region_name": "Shadow Temple 3 Spinning Pots Rupees",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ 3 Spinning Pots Rupee 1": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 2": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 3": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 4": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 5": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 6": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 7": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 8": "True",
"Shadow Temple MQ 3 Spinning Pots Rupee 9": "True"
}
},
{
"region_name": "Shadow Temple Before Boss",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple MQ GS Near Boss": "has_projectile(adult) or can_use(Dins_Fire)"
},
"exits": {
"Shadow Temple Boss Door": "True"
}
}
]

View File

@ -15,10 +15,18 @@
"locations": {
"Shadow Temple Map Chest": "True",
"Shadow Temple Hover Boots Chest": "True",
"Shadow Temple Whispering Walls Front Pot 1": "True",
"Shadow Temple Whispering Walls Front Pot 2": "True",
"Shadow Temple Whispering Walls Left Pot 1": "True",
"Shadow Temple Whispering Walls Left Pot 2": "True",
"Shadow Temple Whispering Walls Left Pot 3": "True",
"Shadow Temple Whispering Walls Flying Pot": "True",
"Shadow Temple Whispering Walls Near Dead Hand Pot": "True",
"Shadow Temple Map Chest Room Pot 1": "True",
"Shadow Temple Map Chest Room Pot 2": "True",
"Nut Pot": "True"
},
"exits": {
"Shadow Temple Entryway": "True",
"Shadow Temple First Beamos": "Hover_Boots"
}
},
@ -30,7 +38,17 @@
"Shadow Temple Early Silver Rupee Chest": "True"
},
"exits": {
"Shadow Temple Huge Pit": "has_explosives and (Small_Key_Shadow_Temple, 1)"
# If the shortcut is open, reverse shadow becomes an option, so we need to check for 4 keys with Lens/trick
# or all 5 keys. If the moving platform lens trick is off, forward shadow is the only way to access
# the huge pit checks without Lens of Truth. Getting to the invisible blades room in reverse uses the falling
# elevator near the Beamos.
# Also, we only need to check shortcut keys here and at boat, since key requirements are always the same.
"Shadow Temple Huge Pit": "
has_explosives and
(((Small_Key_Shadow_Temple, 1) and not shadow_temple_shortcuts) or
(Small_Key_Shadow_Temple, 5) or
((Small_Key_Shadow_Temple, 4) and (logic_lens_shadow_platform or can_use(Lens_of_Truth))))",
"Shadow Temple Boat": "shadow_temple_shortcuts"
}
},
{
@ -42,52 +60,144 @@
"Shadow Temple Falling Spikes Lower Chest": "True",
"Shadow Temple Falling Spikes Upper Chest": "logic_shadow_umbrella or Progressive_Strength_Upgrade",
"Shadow Temple Falling Spikes Switch Chest": "logic_shadow_umbrella or Progressive_Strength_Upgrade",
"Shadow Temple Invisible Spikes Chest": "
(Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_back or can_use(Lens_of_Truth))",
"Shadow Temple Freestanding Key": "
(Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_back or can_use(Lens_of_Truth))
and Progressive_Hookshot and
(Bombs or Progressive_Strength_Upgrade or
(logic_shadow_freestanding_key and has_bombchus))",
"Shadow Temple GS Like Like Room": "True",
"Shadow Temple GS Falling Spikes Room": "logic_shadow_umbrella_gs or Progressive_Hookshot",
"Shadow Temple GS Single Giant Pot": "
(Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_back or can_use(Lens_of_Truth))
and Progressive_Hookshot"
"Shadow Temple Invisible Blades Recovery Heart 1": "can_play(Song_of_Time)",
"Shadow Temple Invisible Blades Recovery Heart 2": "can_play(Song_of_Time)",
"Shadow Temple Falling Spikes Lower Pot 1": "True",
"Shadow Temple Falling Spikes Lower Pot 2": "True",
"Shadow Temple Falling Spikes Upper Pot 1": "logic_shadow_umbrella or Progressive_Strength_Upgrade",
"Shadow Temple Falling Spikes Upper Pot 2": "logic_shadow_umbrella or Progressive_Strength_Upgrade",
"Shadow Temple GS Invisible Blades Room": "True",
"Shadow Temple GS Falling Spikes Room": "logic_shadow_umbrella_gs or Hookshot"
},
"exits": {
"Shadow Temple Wind Tunnel": "
(logic_lens_shadow_back or can_use(Lens_of_Truth)) and
Progressive_Hookshot and (Small_Key_Shadow_Temple, 3)"
"Shadow Temple Invisible Spikes": "
(Small_Key_Shadow_Temple, 2) and (logic_lens_shadow_platform or can_use(Lens_of_Truth))"
}
},
{
"region_name": "Shadow Temple Invisible Spikes",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Invisible Spikes Chest": "True",
"Shadow Temple Freestanding Key": "
Hookshot and
(Bombs or Progressive_Strength_Upgrade or
(logic_shadow_freestanding_key and has_bombchus))",
"Shadow Temple GS Single Giant Pot": "Hookshot"
},
"exits": {
"Shadow Temple Wind Tunnel": "Hookshot and (Small_Key_Shadow_Temple, 3)",
"Shadow Temple Huge Pit": "logic_lens_shadow_platform or can_use(Lens_of_Truth)"
}
},
{
"region_name": "Shadow Temple Wind Tunnel",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Wind Hint Chest": "True",
"Shadow Temple After Wind Enemy Chest": "True",
"Shadow Temple After Wind Hidden Chest": "True",
"Shadow Temple GS Near Ship": "can_use(Longshot) and (Small_Key_Shadow_Temple, 4)"
"Shadow Temple Wind Hint Chest": "True"
},
"exits": {
"Shadow Temple Beyond Boat": "can_play(Zeldas_Lullaby) and (Small_Key_Shadow_Temple, 4)"
"Shadow Temple After Wind": "True",
# Reverse Shadow assumes 4 keys at both ends, so no need to check keys here
"Shadow Temple Invisible Spikes": "Hookshot"
}
},
{
"region_name": "Shadow Temple After Wind",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple After Wind Enemy Chest": "True",
"Shadow Temple After Wind Hidden Chest": "has_explosives",
"Shadow Temple After Wind Pot 1": "True",
"Shadow Temple After Wind Pot 2": "True",
"Shadow Temple After Wind Flying Pot 1": "True",
"Shadow Temple After Wind Flying Pot 2": "True"
},
"exits": {
"Shadow Temple Boat": "(Small_Key_Shadow_Temple, 4)",
"Shadow Temple Wind Tunnel": "True"
}
},
{
"region_name": "Shadow Temple Boat",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Before Boat Recovery Heart 1": "can_use(Distant_Scarecrow)",
"Shadow Temple Before Boat Recovery Heart 2": "can_use(Distant_Scarecrow)",
"Shadow Temple GS Near Ship": "Longshot"
},
"exits": {
"Shadow Temple After Wind": "(Small_Key_Shadow_Temple, 4)",
"Shadow Temple Beyond Boat": "can_play(Zeldas_Lullaby)"
}
},
{
"region_name": "Shadow Temple Beyond Boat",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Invisible Floormaster Chest": "True",
"Shadow Temple Spike Walls Left Chest": "can_use(Dins_Fire)",
"Shadow Temple Boss Key Chest": "can_use(Dins_Fire)",
"Shadow Temple Invisible Floormaster Chest": "True",
"Shadow Temple Bongo Bongo Heart": "
(Small_Key_Shadow_Temple, 5) and Boss_Key_Shadow_Temple and
(Bow or can_use(Distant_Scarecrow) or (logic_shadow_statue and has_bombchus))",
"Bongo Bongo": "
(Small_Key_Shadow_Temple, 5) and Boss_Key_Shadow_Temple and
(Bow or can_use(Distant_Scarecrow) or (logic_shadow_statue and has_bombchus))",
"Shadow Temple After Boat Pot": "True",
"Shadow Temple Invisible Floormaster Pot 1": "True",
"Shadow Temple Invisible Floormaster Pot 2": "True",
"Shadow Temple Spike Walls Pot": "True",
"Shadow Temple GS Triple Giant Pot": "True"
},
"exits": {
"Shadow Temple 3 Spinning Pots Rupees": "Bombs or Progressive_Strength_Upgrade",
"Shadow Temple Beyond Boat Scarecrow": "can_use(Distant_Scarecrow)",
"Shadow Temple Before Boss": "
Bow or (logic_shadow_statue and has_bombchus) or shadow_temple_shortcuts"
}
},
{
"region_name": "Shadow Temple 3 Spinning Pots Rupees",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple 3 Spinning Pots Rupee 1": "True",
"Shadow Temple 3 Spinning Pots Rupee 2": "True",
"Shadow Temple 3 Spinning Pots Rupee 3": "True",
"Shadow Temple 3 Spinning Pots Rupee 4": "True",
"Shadow Temple 3 Spinning Pots Rupee 5": "True",
"Shadow Temple 3 Spinning Pots Rupee 6": "True",
"Shadow Temple 3 Spinning Pots Rupee 7": "True",
"Shadow Temple 3 Spinning Pots Rupee 8": "True",
"Shadow Temple 3 Spinning Pots Rupee 9": "True"
}
},
{
"region_name": "Shadow Temple Beyond Boat Scarecrow",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple After Boat Upper Recovery Heart 1": "True",
"Shadow Temple After Boat Upper Recovery Heart 2": "True"
},
"exits": {
"Shadow Temple Beyond Boat SoT Block": "True"
}
},
{
"region_name": "Shadow Temple Beyond Boat SoT Block",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple After Boat Lower Recovery Heart": "True"
},
"exits": {
"Shadow Temple Beyond Boat Scarecrow": "can_use(Scarecrow)",
"Shadow Temple Before Boss": "True"
}
},
{
"region_name": "Shadow Temple Before Boss",
"dungeon": "Shadow Temple",
"locations": {
"Shadow Temple Near Boss Pot 1": "True",
"Shadow Temple Near Boss Pot 2": "True"
},
"exits": {
"Shadow Temple Beyond Boat SoT Block": "can_play(Song_of_Time)",
"Shadow Temple Boss Door": "(Small_Key_Shadow_Temple, 5)"
}
}
]

View File

@ -5,17 +5,21 @@
"locations": {
"Spirit Temple MQ Entrance Front Left Chest": "True",
"Spirit Temple MQ Entrance Back Left Chest": "
here(can_blast_or_smash) and
(can_use(Slingshot) or can_use(Bow))",
here(can_blast_or_smash) and (can_use(Slingshot) or can_use(Bow))",
"Spirit Temple MQ Entrance Back Right Chest": "
has_bombchus or can_use(Bow) or can_use(Hookshot) or
can_use(Slingshot) or can_use(Boomerang)"
can_use(Slingshot) or can_use(Boomerang)",
"Spirit Temple MQ Lobby Pot 1": "True",
"Spirit Temple MQ Lobby Pot 2": "True",
"Spirit Temple MQ Lobby Pot 3": "True",
"Spirit Temple MQ Lobby Pot 4": "True"
},
"exits": {
"Desert Colossus From Spirit Lobby": "True",
"Child Spirit Temple": "is_child",
"Adult Spirit Temple": "
has_bombchus and can_use(Longshot) and can_use(Silver_Gauntlets)"
can_use(Longshot) and
((can_use(Silver_Gauntlets) and has_bombchus) or spirit_temple_shortcuts)"
}
},
{
@ -24,18 +28,29 @@
"locations": {
"Spirit Temple MQ Child Hammer Switch Chest": "
at('Adult Spirit Temple', (Small_Key_Spirit_Temple, 7) and Megaton_Hammer)",
"Spirit Temple MQ Map Room Enemy Chest": "
(Sticks or Kokiri_Sword) and
has_bombchus and Slingshot and can_use(Dins_Fire)",
"Spirit Temple MQ Map Chest": "Sticks or Kokiri_Sword or Bombs",
"Spirit Temple MQ Map Room Enemy Chest": "
(Sticks or Kokiri_Sword) and has_bombchus and Slingshot and can_use(Dins_Fire)",
"Spirit Temple MQ Silver Block Hallway Chest": "
has_bombchus and (Small_Key_Spirit_Temple, 7) and Slingshot and
(can_use(Dins_Fire) or
at('Adult Spirit Temple', (can_use(Fire_Arrows) or
(logic_spirit_mq_frozen_eye and can_use(Bow) and can_play(Song_of_Time)))))",
"Spirit Temple MQ Child Recovery Heart 1": "can_use(Slingshot) or can_use(Boomerang)",
"Spirit Temple MQ Child Recovery Heart 2": "can_use(Slingshot) or can_use(Boomerang)",
"Spirit Temple MQ Child Torch Slugs Room Pot": "True",
"Spirit Temple MQ Child 3 Gibdo Room Pot 1": "
(Sticks or Kokiri_Sword or (Bombs and can_use(Dins_Fire))) and has_bombchus and Slingshot",
"Spirit Temple MQ Child 3 Gibdo Room Pot 2": "
(Sticks or Kokiri_Sword or (Bombs and can_use(Dins_Fire))) and has_bombchus and Slingshot",
"Spirit Temple MQ Child Stalfos Fight Pot 1": "
(Sticks or Kokiri_Sword) and has_bombchus and Slingshot",
"Spirit Temple MQ Child Stalfos Fight Pot 2": "
(Sticks or Kokiri_Sword) and has_bombchus and Slingshot",
"Spirit Temple MQ Child Stalfos Fight Pot 3": "
(Sticks or Kokiri_Sword) and has_bombchus and Slingshot",
"Fairy Pot": "
has_bottle and (Sticks or Kokiri_Sword) and
has_bombchus and Slingshot"
has_bottle and (Sticks or Kokiri_Sword) and has_bombchus and Slingshot"
},
"exits": {
"Spirit Temple Shared": "has_bombchus and (Small_Key_Spirit_Temple, 2)"
@ -45,39 +60,27 @@
"region_name": "Adult Spirit Temple",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple MQ Child Climb South Chest": "(Small_Key_Spirit_Temple, 7)",
"Spirit Temple MQ Statue Room Lullaby Chest": "can_play(Zeldas_Lullaby)",
"Spirit Temple MQ Statue Room Invisible Chest": "
logic_lens_spirit_mq or can_use(Lens_of_Truth)",
"Spirit Temple MQ Beamos Room Chest": "(Small_Key_Spirit_Temple, 5)",
"Spirit Temple MQ Chest Switch Chest": "
(Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time)",
"Spirit Temple MQ Boss Key Chest": "
(Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time) and Mirror_Shield",
"Spirit Temple MQ GS Nine Thrones Room West": "(Small_Key_Spirit_Temple, 7)",
"Spirit Temple MQ GS Nine Thrones Room North": "(Small_Key_Spirit_Temple, 7)"
"Spirit Temple MQ Child Climb South Chest": "(Small_Key_Spirit_Temple, 7) and has_explosives",
"Spirit Temple MQ Statue Room Lullaby Chest": "can_play(Zeldas_Lullaby) and can_break_crate",
"Spirit Temple MQ Statue Room Invisible Chest": "logic_lens_spirit_mq or can_use(Lens_of_Truth)"
},
"exits": {
"Lower Adult Spirit Temple": "
Mirror_Shield and (can_use(Fire_Arrows) or
(logic_spirit_mq_lower_adult and can_use(Dins_Fire) and Bow))",
"Spirit Temple Shared": "True",
"Spirit Temple Boss Area": "
(Small_Key_Spirit_Temple, 6) and can_play(Zeldas_Lullaby) and Megaton_Hammer",
"Mirror Shield Hand": "
(Small_Key_Spirit_Temple, 5) and can_play(Song_of_Time) and
(logic_lens_spirit_mq or can_use(Lens_of_Truth))"
"Lower Adult Spirit Temple": "
Mirror_Shield and
(can_use(Fire_Arrows) or (logic_spirit_mq_lower_adult and can_use(Dins_Fire)))",
"Spirit Temple Beamos Room": "(Small_Key_Spirit_Temple, 5)",
"Spirit Temple Boss Door": "spirit_temple_shortcuts"
}
},
{
#In this region, child reachability really means age-unknown, but with the caveat
#that child has as least entered the dungeon. is_adult means is_adult as usual.
#All child specific logic must be anded with 7 keys to convert child-as-unknown-age
#back to child.
# In this region, child reachability really means age-unknown, but with the caveat that child has
# as least entered the dungeon. is_adult means is_adult as usual. All child specific logic must be
# anded with 7 keys to convert child-as-unknown-age back to child.
"region_name": "Spirit Temple Shared",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple MQ Child Climb North Chest": "(Small_Key_Spirit_Temple, 6)",
"Spirit Temple MQ Child Climb North Chest": "(Small_Key_Spirit_Temple, 6) and has_explosives",
"Spirit Temple MQ Compass Chest": "
(can_use(Slingshot) and (Small_Key_Spirit_Temple, 7)) or
can_use(Bow) or
@ -85,21 +88,41 @@
"Spirit Temple MQ Sun Block Room Chest": "
can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or
is_adult",
"Spirit Temple Silver Gauntlets Chest": "
((Small_Key_Spirit_Temple, 7) and
(can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or is_adult)) or
((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and (has_explosives or Nuts) and
(logic_lens_spirit_mq or can_use(Lens_of_Truth)))",
"Spirit Temple MQ Child Climb Pot": "(Small_Key_Spirit_Temple, 6)",
"Spirit Temple MQ Central Chamber Floor Pot 1": "True",
"Spirit Temple MQ Central Chamber Floor Pot 2": "True",
"Spirit Temple MQ Central Chamber Floor Pot 3": "True",
"Spirit Temple MQ Central Chamber Top Left Pot (Left)": "
(is_adult and (Hover_Boots or logic_spirit_lobby_jump)) or
can_play(Song_of_Time)",
"Spirit Temple MQ Central Chamber Top Left Pot (Right)": "
(is_child and Boomerang and (Kokiri_Sword or Sticks) and (Small_Key_Spirit_Temple, 7)) or
(is_adult and (Hover_Boots or logic_spirit_lobby_jump)) or
can_play(Song_of_Time) or
(Boomerang and (Kokiri_Sword or Sticks) and (Hover_Boots or logic_spirit_lobby_jump))",
"Spirit Temple MQ Sun Block Room Pot 1": "
can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or
is_adult",
"Spirit Temple MQ Sun Block Room Pot 2": "
can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or
is_adult",
"Spirit Temple MQ Central Chamber Crate 1": "can_break_crate",
"Spirit Temple MQ Central Chamber Crate 2": "can_break_crate",
"Spirit Temple MQ GS Sun Block Room": "
(logic_spirit_mq_sun_block_gs and Boomerang and
(can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot)) or
is_adult"
},
"exits": {
"Silver Gauntlets Hand": "
((Small_Key_Spirit_Temple, 7) and
(can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or is_adult)) or
((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and
(logic_lens_spirit_mq or can_use(Lens_of_Truth)))",
"Desert Colossus": "
((Small_Key_Spirit_Temple, 7) and
(can_play(Song_of_Time) or logic_spirit_mq_sun_block_sot or is_adult)) or
((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and
((Small_Key_Spirit_Temple, 4) and can_play(Song_of_Time) and (has_explosives or Nuts) and
(logic_lens_spirit_mq or can_use(Lens_of_Truth)) and is_adult)"
}
},
@ -110,38 +133,76 @@
"Spirit Temple MQ Leever Room Chest": "True",
"Spirit Temple MQ Symphony Room Chest": "
(Small_Key_Spirit_Temple, 7) and Megaton_Hammer and Ocarina and
Song_of_Time and Eponas_Song and Suns_Song and
Song_of_Storms and Zeldas_Lullaby",
Song_of_Time and Eponas_Song and Suns_Song and Song_of_Storms and Zeldas_Lullaby",
"Spirit Temple MQ Entrance Front Right Chest": "Megaton_Hammer",
"Spirit Temple MQ Below 4 Wallmasters Pot 1": "True",
"Spirit Temple MQ Below 4 Wallmasters Pot 2": "True",
"Spirit Temple MQ GS Leever Room": "True",
"Spirit Temple MQ GS Symphony Room": "
(Small_Key_Spirit_Temple, 7) and Megaton_Hammer and Ocarina and
Song_of_Time and Eponas_Song and Suns_Song and
Song_of_Storms and Zeldas_Lullaby"
Song_of_Time and Eponas_Song and Suns_Song and Song_of_Storms and Zeldas_Lullaby"
}
},
{
"region_name": "Spirit Temple Boss Area",
"region_name": "Spirit Temple Beamos Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple MQ Mirror Puzzle Invisible Chest": "
logic_lens_spirit_mq or can_use(Lens_of_Truth)",
"Spirit Temple Twinrova Heart": "Mirror_Shield and Boss_Key_Spirit_Temple",
"Twinrova": "Mirror_Shield and Boss_Key_Spirit_Temple"
"Spirit Temple MQ Beamos Room Chest": "has_explosives"
},
"exits": {
"Spirit Temple Beyond Beamos Room": "can_play(Song_of_Time) and (has_explosives or Nuts)",
"Spirit Temple Shifting Wall": "(Small_Key_Spirit_Temple, 6)"
}
},
{
"region_name": "Mirror Shield Hand",
"region_name": "Spirit Temple Beyond Beamos Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Mirror Shield Chest": "True"
"Spirit Temple MQ Chest Switch Chest": "True",
"Spirit Temple MQ Boss Key Chest": "Mirror_Shield",
"Spirit Temple Mirror Shield Chest": "logic_lens_spirit_mq or can_use(Lens_of_Truth)"
}
},
{
"region_name": "Silver Gauntlets Hand",
"region_name": "Spirit Temple Shifting Wall",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Silver Gauntlets Chest": "True"
"Spirit Temple MQ Shifting Wall Pot 1": "True",
"Spirit Temple MQ Shifting Wall Pot 2": "True",
"Spirit Temple MQ After Shifting Wall Room Pot 1": "True",
"Spirit Temple MQ After Shifting Wall Room Pot 2": "True",
"Spirit Temple MQ GS Nine Thrones Room West": "(Small_Key_Spirit_Temple, 7)",
"Spirit Temple MQ GS Nine Thrones Room North": "(Small_Key_Spirit_Temple, 7)"
},
"exits": {
"Spirit Temple Big Mirror Room": "can_play(Zeldas_Lullaby)"
}
},
{
"region_name": "Spirit Temple Big Mirror Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple MQ Big Mirror Pot 1": "True",
"Spirit Temple MQ Big Mirror Pot 2": "True",
"Spirit Temple MQ Big Mirror Pot 3": "True",
"Spirit Temple MQ Big Mirror Pot 4": "True",
"Spirit Temple MQ Big Mirror Crate 1": "can_break_crate",
"Spirit Temple MQ Big Mirror Crate 2": "can_break_crate",
"Spirit Temple MQ Big Mirror Crate 3": "can_break_crate",
"Spirit Temple MQ Big Mirror Crate 4": "can_break_crate"
},
"exits": {
"Spirit Temple Mirror Puzzle": "Megaton_Hammer"
}
},
{
"region_name": "Spirit Temple Mirror Puzzle",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple MQ Mirror Puzzle Invisible Chest": "logic_lens_spirit_mq or can_use(Lens_of_Truth)"
},
"exits": {
"Spirit Temple Boss Door": "Mirror_Shield"
}
}
]

View File

@ -2,191 +2,239 @@
{
"region_name": "Spirit Temple Lobby",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Lobby Pot 1": "True",
"Spirit Temple Lobby Pot 2": "True",
"Spirit Temple Lobby Flying Pot 1": "True",
"Spirit Temple Lobby Flying Pot 2": "True"
},
"exits": {
"Desert Colossus From Spirit Lobby": "True",
"Child Spirit Temple": "is_child",
"Early Adult Spirit Temple": "can_use(Silver_Gauntlets)"
"Child Spirit Temple": "
is_child and
(Sticks or has_explosives or
((Nuts or Boomerang) and (Kokiri_Sword or Slingshot))) and
(Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu))",
"Child Spirit Before Locked Door": "is_child",
"Early Adult Spirit Temple": "can_use(Silver_Gauntlets)",
"Spirit Temple Central Chamber": "is_adult and spirit_temple_shortcuts"
}
},
{
"region_name": "Child Spirit Temple",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Child Bridge Chest": "
(Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu)) and
(Sticks or has_explosives or
((Nuts or Boomerang) and
(Kokiri_Sword or Slingshot)))",
"Spirit Temple Child Early Torches Chest": "
(Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu)) and
(Sticks or has_explosives or
((Nuts or Boomerang) and (Kokiri_Sword or Slingshot))) and
(Sticks or can_use(Dins_Fire))",
"Spirit Temple GS Metal Fence": "
(Boomerang or Slingshot or (has_bombchus and logic_spirit_child_bombchu)) and
(Sticks or has_explosives or
((Nuts or Boomerang) and (Kokiri_Sword or Slingshot)))"
},
"exits": {
"Child Spirit Before Locked Door": "True"
"Spirit Temple Child Bridge Chest": "True",
"Spirit Temple Child Early Torches Chest": "Sticks or can_use(Dins_Fire)",
"Spirit Temple Child Bridge Flying Pot": "True",
"Spirit Temple Child Anubis Pot": "True",
"Spirit Temple GS Metal Fence": "True",
"Deku Shield Pot": "fix_broken_drops"
}
},
{
"region_name": "Child Spirit Before Locked Door",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Before Child Climb Small Wooden Crate 1": "True",
"Spirit Temple Before Child Climb Small Wooden Crate 2": "True",
"Nut Crate": "True"
},
"exits": {
"Child Spirit Temple Climb": "(Small_Key_Spirit_Temple, 1)"
}
},
{
"region_name": "Early Adult Spirit Temple",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Compass Chest": "Hookshot and can_play(Zeldas_Lullaby)",
# The mid-air silver rupee can be collected with a jumpslash.
"Spirit Temple Early Adult Right Chest": "
Bow or Hookshot or has_bombchus or (Bombs and logic_spirit_lower_adult_switch)",
"Spirit Temple GS Boulder Room": "
can_play(Song_of_Time) and
(Bow or Hookshot or has_bombchus or (Bombs and logic_spirit_lower_adult_switch))"
},
"exits": {
"Spirit Temple Central Chamber": "(Small_Key_Spirit_Temple, 1)",
"Adult Spirit Temple Climb": "(Small_Key_Spirit_Temple, 3)"
}
},
# In the following two regions, child and adult reachability actually means age-unknown, but with
# the caveat that that age can potentially enter the area. Routes must be anded with 5 keys for
# child or 3 keys (or shortcuts on) for adult before they can use only items specific to that age.
# Age-unknown routes do not specify age and must include the necessary items for both ages, so
# that the checks can be collected regardless of which age actually has entered the area.
# Routes that use two keys are age-unknown, where the checks are expected to be collected as
# adult, but child might collect them instead if out-of-logic explosives have been found. Checking
# bombchus_in_logic on and entrance_shuffle off ensures that those explosives cannot be exhausted.
# Age-unknown logic is not deadend-proof in rare cases where some non-repeatable access is used
# to reach the temple (only possible with Entrance Randomizer). This trade-off is worth it to
# increase item placement variety, particularly when keys are shuffled within their own dungeons.
{
"region_name": "Child Spirit Temple Climb",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Child Climb North Chest": "
has_projectile(both) or
(((Small_Key_Spirit_Temple, 3) or
((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and
can_use(Silver_Gauntlets) and has_projectile(adult)) or
((Small_Key_Spirit_Temple, 5) and is_child and
has_projectile(child))",
(is_child and has_projectile(child) and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and has_projectile(adult) and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle))) or
has_projectile(both)",
"Spirit Temple Child Climb East Chest": "
has_projectile(both) or
(((Small_Key_Spirit_Temple, 3) or
((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and
can_use(Silver_Gauntlets) and has_projectile(adult)) or
((Small_Key_Spirit_Temple, 5) and is_child and
has_projectile(child))",
(is_child and has_projectile(child) and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and has_projectile(adult) and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle))) or
has_projectile(both)",
"Spirit Temple Child Climb Pot": "True",
"Spirit Temple GS Sun on Floor Room": "
(is_child and has_projectile(child) and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and (has_projectile(adult) or can_take_damage) and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle))) or
has_projectile(both) or can_use(Dins_Fire) or
(can_take_damage and (Sticks or Kokiri_Sword or has_projectile(child))) or
(is_child and
(Small_Key_Spirit_Temple, 5) and has_projectile(child)) or
(((Small_Key_Spirit_Temple, 3) or
((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and
can_use(Silver_Gauntlets) and
(has_projectile(adult) or can_take_damage))"
(can_take_damage and (Sticks or Kokiri_Sword or has_projectile(child)))"
},
"exits": {
"Spirit Temple Central Chamber": "has_explosives",
"Child Spirit Before Locked Door": "(Small_Key_Spirit_Temple, 5)"
}
},
{
"region_name": "Early Adult Spirit Temple",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Compass Chest": "
can_use(Hookshot) and can_play(Zeldas_Lullaby)",
"Spirit Temple Early Adult Right Chest": "
Bow or Progressive_Hookshot or has_bombchus or (Bombs and logic_spirit_lower_adult_switch)",
#requires a very specific Bombchu use, Hover Boots can be skipped by jumping on top of the rolling rock.
"Spirit Temple First Mirror Left Chest": "(Small_Key_Spirit_Temple, 3)",
"Spirit Temple First Mirror Right Chest": "(Small_Key_Spirit_Temple, 3)",
"Spirit Temple GS Boulder Room": "
can_play(Song_of_Time) and
(Bow or Progressive_Hookshot or has_bombchus or (Bombs and logic_spirit_lower_adult_switch))"
},
"exits": {
"Spirit Temple Central Chamber": "(Small_Key_Spirit_Temple, 1)"
}
},
{
"region_name": "Spirit Temple Central Chamber",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Map Chest": "
((has_explosives or (Small_Key_Spirit_Temple, 3) or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and
(can_use(Dins_Fire) or
(((Magic_Meter and Fire_Arrows) or logic_spirit_map_chest) and Bow and Sticks))) or
((Small_Key_Spirit_Temple, 5) and has_explosives and
can_use(Sticks)) or
((Small_Key_Spirit_Temple, 3) and
(can_use(Fire_Arrows) or (logic_spirit_map_chest and Bow)) and
can_use(Silver_Gauntlets))",
(is_child and Sticks and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and (has_fire_source or (logic_spirit_map_chest and Bow)) and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts)) or
((can_use(Dins_Fire) or (((Magic_Meter and Fire_Arrows) or logic_spirit_map_chest) and Bow and Sticks)) and
(has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)))",
"Spirit Temple Sun Block Room Chest": "
((has_explosives or (Small_Key_Spirit_Temple, 3) or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and
(can_use(Dins_Fire) or
(((Magic_Meter and Fire_Arrows) or logic_spirit_sun_chest) and Bow and Sticks))) or
((Small_Key_Spirit_Temple, 5) and has_explosives and
can_use(Sticks)) or
((Small_Key_Spirit_Temple, 3) and
(can_use(Fire_Arrows) or (logic_spirit_sun_chest and Bow)) and
can_use(Silver_Gauntlets))",
"Spirit Temple Statue Room Hand Chest": "
(Small_Key_Spirit_Temple, 3) and can_use(Silver_Gauntlets) and
can_play(Zeldas_Lullaby)",
"Spirit Temple Statue Room Northeast Chest": "
(Small_Key_Spirit_Temple, 3) and can_use(Silver_Gauntlets) and can_play(Zeldas_Lullaby) and
(Progressive_Hookshot or Hover_Boots or logic_spirit_lobby_jump)",
"Spirit Temple GS Hall After Sun Block Room": "
(has_explosives and Boomerang and Progressive_Hookshot) or
(can_use(Boomerang) and (Small_Key_Spirit_Temple, 5) and has_explosives) or
(Progressive_Hookshot and can_use(Silver_Gauntlets) and
((Small_Key_Spirit_Temple, 3) or
((Small_Key_Spirit_Temple, 2) and Boomerang and bombchus_in_logic and not entrance_shuffle)))",
"Spirit Temple GS Lobby": "
((has_explosives or (Small_Key_Spirit_Temple, 3) or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)) and
logic_spirit_lobby_gs and Boomerang and (Progressive_Hookshot or Hover_Boots or logic_spirit_lobby_jump)) or
(logic_spirit_lobby_gs and (Small_Key_Spirit_Temple, 5) and has_explosives and can_use(Boomerang)) or
((Small_Key_Spirit_Temple, 3) and can_use(Silver_Gauntlets) and (Progressive_Hookshot or Hover_Boots or logic_spirit_lobby_jump))"
},
"exits": {
"Spirit Temple Outdoor Hands": "True",
"Spirit Temple Beyond Central Locked Door": "
(Small_Key_Spirit_Temple, 4) and can_use(Silver_Gauntlets)",
"Child Spirit Temple Climb": "True"
}
},
{
"region_name": "Spirit Temple Outdoor Hands",
"dungeon": "Spirit Temple",
"locations": {
(is_child and Sticks and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and (has_fire_source or (logic_spirit_sun_chest and Bow)) and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts)) or
((can_use(Dins_Fire) or (((Magic_Meter and Fire_Arrows) or logic_spirit_sun_chest) and Bow and Sticks)) and
(has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)))",
# With longshot and explosives, right hand is reachable as adult after opening either
# upper door. Because some of the keys cannot be spent without adult accessing the
# main body of the dungeon, this route is able to be age-unknown, where child can be
# expected to reach it as long as adult cannot enter. Because we cannot truly know
# whether adult can enter, child must still possess the items that adult would use.
"Spirit Temple Silver Gauntlets Chest": "
((Small_Key_Spirit_Temple, 3) and (Progressive_Hookshot, 2) and has_explosives) or
(Small_Key_Spirit_Temple, 5)",
"Spirit Temple Mirror Shield Chest": "
(Small_Key_Spirit_Temple, 4) and can_use(Silver_Gauntlets) and has_explosives"
(Small_Key_Spirit_Temple, 5) or
(has_explosives and Longshot and (Small_Key_Spirit_Temple, 3))",
"Spirit Temple Central Chamber Flying Pot 1": "
(Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)",
"Spirit Temple Central Chamber Flying Pot 2": "
(Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)",
"Spirit Temple Hall After Sun Block Room Pot 1": "
(Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)",
"Spirit Temple Hall After Sun Block Room Pot 2": "
(Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts or
has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)",
"Spirit Temple GS Lobby": "
(is_child and logic_spirit_lobby_gs and Boomerang and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and (Hookshot or Hover_Boots or logic_spirit_lobby_jump) and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts)) or
(logic_spirit_lobby_gs and Boomerang and (Hookshot or Hover_Boots or logic_spirit_lobby_jump) and
(has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)))",
"Spirit Temple GS Hall After Sun Block Room": "
(is_child and Boomerang and
(Small_Key_Spirit_Temple, 5)) or
(is_adult and Hookshot and
((Small_Key_Spirit_Temple, 3) or spirit_temple_shortcuts)) or
(Boomerang and Hookshot and
(has_explosives or ((Small_Key_Spirit_Temple, 2) and bombchus_in_logic and not entrance_shuffle)))"
},
"exits": {
"Child Spirit Temple Climb": "True",
"Adult Spirit Temple Climb": "spirit_temple_shortcuts and can_use(Hookshot)",
"Spirit Temple Boss Door": "
is_adult and spirit_temple_shortcuts and
(Longshot or (logic_spirit_platform_hookshot and Hookshot))",
# Age-unknown logic is incompatible with the rest of the world.
# Because adult might unlock all doors, child must require all 5 keys to pass.
"Desert Colossus": "
(is_child and (Small_Key_Spirit_Temple, 5)) or
(can_use(Silver_Gauntlets) and
(((Small_Key_Spirit_Temple, 3) and has_explosives) or (Small_Key_Spirit_Temple, 5)))"
(Small_Key_Spirit_Temple, 5) or
(is_adult and has_explosives and (Small_Key_Spirit_Temple, 3))"
}
},
{
"region_name": "Spirit Temple Beyond Central Locked Door",
"region_name": "Adult Spirit Temple Climb",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Near Four Armos Chest": "Mirror_Shield and has_explosives",
"Spirit Temple Hallway Left Invisible Chest": "(logic_lens_spirit or can_use(Lens_of_Truth)) and has_explosives",
"Spirit Temple Hallway Right Invisible Chest": "(logic_lens_spirit or can_use(Lens_of_Truth)) and has_explosives"
"Spirit Temple First Mirror Left Chest": "True",
"Spirit Temple First Mirror Right Chest": "True",
"Spirit Temple Statue Room Hand Chest": "can_play(Zeldas_Lullaby)",
"Spirit Temple Statue Room Northeast Chest": "
can_play(Zeldas_Lullaby) and
(Hookshot or Hover_Boots or logic_spirit_lobby_jump)",
"Spirit Temple Adult Climb Flying Pot 1": "True",
"Spirit Temple Adult Climb Flying Pot 2": "True"
},
"exits": {
"Spirit Temple Beyond Final Locked Door": "
(Small_Key_Spirit_Temple, 5) and
(logic_spirit_wall or can_use(Longshot) or has_bombchus or
((Bombs or Nuts or can_use(Dins_Fire)) and
(Bow or can_use(Hookshot) or Megaton_Hammer)))"
"Early Adult Spirit Temple": "(Small_Key_Spirit_Temple, 5)",
"Spirit Temple Anubis Room": "(Small_Key_Spirit_Temple, 4)"
}
},
{
"region_name": "Spirit Temple Beyond Final Locked Door",
"region_name": "Spirit Temple Anubis Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Beamos Hall Pot": "True"
},
"exits": {
"Spirit Temple Beyond Anubis Room": "has_explosives",
"Spirit Temple Big Mirror Room": "
(Small_Key_Spirit_Temple, 5) and
(logic_spirit_wall or Longshot or has_bombchus or
((Bombs or Nuts or can_use(Dins_Fire)) and
(Bow or Hookshot or Megaton_Hammer)))"
}
},
{
"region_name": "Spirit Temple Beyond Anubis Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Near Four Armos Chest": "Mirror_Shield",
"Spirit Temple Hallway Left Invisible Chest": "
logic_lens_spirit or can_use(Lens_of_Truth)",
"Spirit Temple Hallway Right Invisible Chest": "
logic_lens_spirit or can_use(Lens_of_Truth)",
"Spirit Temple Mirror Shield Chest": "True"
}
},
{
"region_name": "Spirit Temple Big Mirror Room",
"dungeon": "Spirit Temple",
"locations": {
"Spirit Temple Boss Key Chest": "
can_play(Zeldas_Lullaby) and Bow and
Progressive_Hookshot",
can_play(Zeldas_Lullaby) and Bow and Hookshot",
"Spirit Temple Topmost Chest": "Mirror_Shield",
"Spirit Temple Twinrova Heart": "
Mirror_Shield and has_explosives and
Progressive_Hookshot and Boss_Key_Spirit_Temple",
"Twinrova": "
Mirror_Shield and has_explosives and
Progressive_Hookshot and Boss_Key_Spirit_Temple"
"Spirit Temple Shifting Wall Recovery Heart 1": "Hookshot",
"Spirit Temple Shifting Wall Recovery Heart 2": "Hookshot",
"Spirit Temple Big Mirror Flying Pot 1": "True",
"Spirit Temple Big Mirror Flying Pot 2": "True",
"Spirit Temple Big Mirror Flying Pot 3": "True",
"Spirit Temple Big Mirror Flying Pot 4": "True",
"Spirit Temple Big Mirror Flying Pot 5": "True",
"Spirit Temple Big Mirror Flying Pot 6": "True"
},
"exits": {
"Spirit Temple Boss Door": "
(spirit_temple_shortcuts or (has_explosives and Mirror_Shield)) and Hookshot"
}
}
]

View File

@ -2,75 +2,253 @@
{
"region_name": "Water Temple Lobby",
"dungeon": "Water Temple",
"events": {
"Water Temple Clear": "Boss_Key_Water_Temple and can_use(Longshot)"
},
"locations": {
"Water Temple Morpha Heart": "Boss_Key_Water_Temple and can_use(Longshot)",
"Morpha": "Boss_Key_Water_Temple and can_use(Longshot)"
},
"exits": {
"Lake Hylia": "True",
"Water Temple Dive": "
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and can_use(Iron_Boots)",
"Water Temple Dark Link Region": "
Small_Key_Water_Temple and can_use(Longshot)"
"Water Temple Dive": "is_adult and (Zora_Tunic or logic_fewer_tunic_requirements) and Iron_Boots",
"Water Temple Dark Link Region": "Small_Key_Water_Temple and can_use(Longshot)",
"Water Temple Boss Door": "can_use(Longshot)"
}
},
{
"region_name": "Water Temple Dive",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Map Chest": "has_fire_source and can_use(Hookshot)",
"Water Temple MQ Central Pillar Chest": "
can_use(Zora_Tunic) and can_use(Hookshot) and
((logic_water_mq_central_pillar and can_use(Fire_Arrows)) or
(can_use(Dins_Fire) and can_play(Song_of_Time)))"
"Water Temple MQ Map Chest": "has_fire_source and Hookshot",
"Water Temple MQ L1 Torch Pot 1": "Hookshot or can_play(Zeldas_Lullaby)",
"Water Temple MQ L1 Torch Pot 2": "Hookshot or can_play(Zeldas_Lullaby)",
"Water Temple MQ Lizalfos Hallway Pot 1": "Hookshot or can_play(Zeldas_Lullaby)",
"Water Temple MQ Lizalfos Hallway Pot 2": "Hookshot or can_play(Zeldas_Lullaby)",
"Water Temple MQ Lizalfos Hallway Pot 3": "Hookshot or can_play(Zeldas_Lullaby)",
"Water Temple MQ Central Pillar Upper Crate 1": "can_break_crate",
"Water Temple MQ Central Pillar Upper Crate 2": "can_break_crate",
"Water Temple MQ Lizalfos Hallway Hall Crate 1": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Hall Crate 2": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Hall Crate 3": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Room Crate 1": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Room Crate 2": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Room Crate 3": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Room Crate 4": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)",
"Water Temple MQ Lizalfos Hallway Room Crate 5": "
can_bonk or (can_play(Zeldas_Lullaby) and can_blast_or_smash)"
},
"exits": {
"Water Temple Below Central Pillar": "
Zora_Tunic and ((logic_water_mq_central_pillar and can_use(Fire_Arrows)) or
(can_use(Dins_Fire) and can_play(Song_of_Time)))",
"Water Temple Storage Room": "Hookshot",
"Water Temple Lowered Water Levels": "can_play(Zeldas_Lullaby)"
}
},
{
"region_name": "Water Temple Below Central Pillar",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Central Pillar Chest": "Hookshot",
"Water Temple MQ Central Pillar Lower Crate 1": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 2": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 3": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 4": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 5": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 6": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 7": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 8": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 9": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 10": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 11": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 12": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 13": "can_bonk",
"Water Temple MQ Central Pillar Lower Crate 14": "can_bonk"
}
},
{
"region_name": "Water Temple Storage Room",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Storage Room Pot 1": "True",
"Water Temple MQ Storage Room Pot 2": "True",
"Water Temple MQ Storage Room Pot 3": "True",
"Water Temple MQ Storage Room Crate 1": "can_break_crate",
"Water Temple MQ Storage Room Crate 2": "can_break_crate",
"Water Temple MQ Storage Room Crate 3": "can_break_crate",
"Water Temple MQ Storage Room Crate 4": "can_break_crate",
"Water Temple MQ Storage Room Crate 5": "can_break_crate",
"Water Temple MQ Storage Room Crate 6": "can_break_crate",
"Water Temple MQ Storage Room Crate 7": "can_break_crate"
}
},
{
"region_name": "Water Temple Lowered Water Levels",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Compass Chest": "
can_use(Bow) or can_use(Dins_Fire) or
at('Water Temple Lobby', can_use(Sticks) and has_explosives)",
"Water Temple MQ Longshot Chest": "can_use(Hookshot)",
"Water Temple MQ GS Lizalfos Hallway": "can_use(Dins_Fire)",
"Water Temple MQ GS Before Upper Water Switch": "can_use(Longshot)"
Bow or can_use(Dins_Fire) or at('Water Temple Lobby', can_use(Sticks))",
"Water Temple MQ Longshot Chest": "Hookshot",
"Water Temple MQ Lizalfos Hallway Gate Pot 1": "can_use(Dins_Fire)",
"Water Temple MQ Lizalfos Hallway Gate Pot 2": "can_use(Dins_Fire)",
"Water Temple MQ Lizalfos Hallway Gate Crate 1": "can_use(Dins_Fire) and can_break_crate",
"Water Temple MQ Lizalfos Hallway Gate Crate 2": "can_use(Dins_Fire) and can_break_crate",
"Water Temple MQ GS Lizalfos Hallway": "can_use(Dins_Fire)"
},
"exits": {
"Water Temple Before Upper Water Switch": "Hookshot"
}
},
{
"region_name": "Water Temple Before Upper Water Switch",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Before Upper Water Switch Pot 1": "True",
"Water Temple MQ Before Upper Water Switch Pot 2": "True",
"Water Temple MQ Before Upper Water Switch Pot 3": "True",
"Water Temple MQ Before Upper Water Switch Lower Crate 1": "can_break_crate",
"Water Temple MQ Before Upper Water Switch Lower Crate 2": "can_break_crate",
"Water Temple MQ Before Upper Water Switch Lower Crate 3": "can_break_crate",
"Water Temple MQ Before Upper Water Switch Lower Crate 4": "can_break_crate",
"Water Temple MQ Before Upper Water Switch Lower Crate 5": "can_break_crate",
"Water Temple MQ Before Upper Water Switch Lower Crate 6": "can_break_crate",
"Water Temple MQ Before Upper Water Switch Upper Crate 1": "Longshot and can_break_crate",
"Water Temple MQ Before Upper Water Switch Upper Crate 2": "Longshot and can_break_crate",
"Water Temple MQ GS Before Upper Water Switch": "Longshot"
}
},
{
"region_name": "Water Temple Dark Link Region",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Boss Key Chest": "
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and can_use(Dins_Fire) and
(logic_water_dragon_jump_dive or can_dive or can_use(Iron_Boots))",
"Water Temple MQ Before Dark Link Lower Pot": "True",
"Water Temple MQ Before Dark Link Top Pot 1": "True",
"Water Temple MQ Before Dark Link Top Pot 2": "True",
"Water Temple MQ Room After Dark Link Pot": "True",
"Water Temple MQ River Pot": "True",
"Water Temple MQ Dragon Statue Near Door Crate 1": "can_break_crate",
"Water Temple MQ Dragon Statue Near Door Crate 2": "can_break_crate",
"Water Temple MQ GS River": "True",
"Fairy Pot": "has_bottle",
"Nut Pot": "True"
},
"exits": {
"Water Temple Basement Gated Areas": "
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and
can_use(Dins_Fire) and can_use(Iron_Boots)"
"Water Temple Dragon Statue": "
(Zora_Tunic or logic_fewer_tunic_requirements) and
(logic_water_dragon_jump_dive or can_dive or Iron_Boots)"
}
},
{
"region_name": "Water Temple Dragon Statue",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Dragon Statue By Torches Crate 1": "can_break_crate",
"Water Temple MQ Dragon Statue By Torches Crate 2": "can_break_crate",
"Water Temple MQ Dragon Statue Submerged Crate 1": "
(Iron_Boots and can_bonk) or (has_bombchus and (can_dive or Iron_Boots))",
"Water Temple MQ Dragon Statue Submerged Crate 2": "
(Iron_Boots and can_bonk) or (has_bombchus and (can_dive or Iron_Boots))",
"Water Temple MQ Dragon Statue Submerged Crate 3": "
(Iron_Boots and can_bonk) or (has_bombchus and (can_dive or Iron_Boots))",
"Water Temple MQ Dragon Statue Submerged Crate 4": "
(Iron_Boots and can_bonk) or (has_bombchus and (can_dive or Iron_Boots))"
},
"exits": {
"Water Temple Boss Key Chest Room": "has_fire_source"
}
},
{
"region_name": "Water Temple Boss Key Chest Room",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Boss Key Chest": "can_use(Dins_Fire)",
"Water Temple MQ Boss Key Chest Room Pot": "True",
"Water Temple MQ Boss Key Chest Room Upper Crate": "can_break_crate",
"Water Temple MQ Boss Key Chest Room Lower Crate 1": "can_break_crate",
"Water Temple MQ Boss Key Chest Room Lower Crate 2": "can_break_crate",
"Water Temple MQ Boss Key Chest Room Lower Crate 3": "can_break_crate",
"Water Temple MQ Boss Key Chest Room Lower Crate 4": "can_break_crate"
},
"exits": {
"Water Temple Basement Gated Areas": "can_use(Dins_Fire) and Iron_Boots"
}
},
{
"region_name": "Water Temple Basement Gated Areas",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Freestanding Key": "
"Water Temple MQ Freestanding Key Area Front Crate 1": "can_break_crate",
"Water Temple MQ Freestanding Key Area Front Crate 2": "can_break_crate",
"Water Temple MQ Freestanding Key Area Submerged Crate 1": "can_bonk or has_bombchus",
"Water Temple MQ Freestanding Key Area Submerged Crate 2": "can_bonk or has_bombchus",
"Water Temple MQ Freestanding Key Area Submerged Crate 3": "can_bonk or has_bombchus",
"Water Temple MQ Freestanding Key Area Submerged Crate 4": "can_bonk or has_bombchus",
"Water Temple MQ Freestanding Key Area Submerged Crate 5": "can_bonk or has_bombchus",
"Water Temple MQ Freestanding Key Area Submerged Crate 6": "can_bonk or has_bombchus",
"Water Temple MQ Triple Wall Torch Submerged Crate 1": "can_bonk or has_bombchus",
"Water Temple MQ Triple Wall Torch Submerged Crate 2": "can_bonk or has_bombchus",
"Water Temple MQ Triple Wall Torch Submerged Crate 3": "can_bonk or has_bombchus",
"Water Temple MQ Triple Wall Torch Submerged Crate 4": "can_bonk or has_bombchus",
"Water Temple MQ Triple Wall Torch Submerged Crate 5": "can_bonk or has_bombchus",
"Water Temple MQ Triple Wall Torch Submerged Crate 6": "can_bonk or has_bombchus"
},
"exits": {
"Water Temple Freestanding Key Room": "
Hover_Boots or can_use(Scarecrow) or logic_water_north_basement_ledge_jump",
"Water Temple MQ GS Triple Wall Torch": "
can_use(Fire_Arrows) and (Hover_Boots or can_use(Scarecrow))",
"Water Temple MQ GS Freestanding Key Area": "
logic_water_mq_locked_gs or ((Small_Key_Water_Temple, 2) and
(Hover_Boots or can_use(Scarecrow) or logic_water_north_basement_ledge_jump))"
"Water Temple Dodongo Room": "logic_water_mq_locked_gs",
"Water Temple Triple Wall Torch": "can_use(Fire_Arrows) and (Hover_Boots or can_use(Scarecrow))"
}
},
{
"region_name": "Water Temple Freestanding Key Room",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Freestanding Key": "can_break_crate",
"Water Temple MQ Freestanding Key Room Pot": "True",
"Water Temple MQ Freestanding Key Room Crate 1": "can_break_crate",
"Water Temple MQ Freestanding Key Room Crate 2": "can_break_crate",
"Water Temple MQ Freestanding Key Room Crate 3": "can_break_crate",
"Water Temple MQ Freestanding Key Room Crate 4": "can_break_crate",
"Water Temple MQ Freestanding Key Room Crate 5": "can_break_crate"
},
"exits": {
"Water Temple Dodongo Room": "(Small_Key_Water_Temple, 2)"
}
},
{
"region_name": "Water Temple Dodongo Room",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Dodongo Room Pot 1": "True",
"Water Temple MQ Dodongo Room Pot 2": "True",
"Water Temple MQ Dodongo Room Lower Crate 1": "can_break_crate",
"Water Temple MQ Dodongo Room Lower Crate 2": "can_break_crate",
"Water Temple MQ Dodongo Room Lower Crate 3": "can_break_crate",
"Water Temple MQ Dodongo Room Upper Crate": "can_break_crate",
"Water Temple MQ Dodongo Room Hall Crate": "can_break_crate",
"Water Temple MQ Freestanding Key Area Behind Gate Crate 1": "can_break_crate",
"Water Temple MQ Freestanding Key Area Behind Gate Crate 2": "can_break_crate",
"Water Temple MQ Freestanding Key Area Behind Gate Crate 3": "can_break_crate",
"Water Temple MQ Freestanding Key Area Behind Gate Crate 4": "can_break_crate",
"Water Temple MQ GS Freestanding Key Area": "True"
},
"exits": {
"Water Temple Freestanding Key Room": "(Small_Key_Water_Temple, 2)"
}
},
{
"region_name": "Water Temple Triple Wall Torch",
"dungeon": "Water Temple",
"locations": {
"Water Temple MQ Triple Wall Torch Pot 1": "True",
"Water Temple MQ Triple Wall Torch Pot 2": "True",
"Water Temple MQ Triple Wall Torch Pot 3": "True",
"Water Temple MQ Triple Wall Torch Pot 4": "True",
"Water Temple MQ Triple Wall Torch Behind Gate Crate 1": "can_break_crate",
"Water Temple MQ Triple Wall Torch Behind Gate Crate 2": "can_break_crate",
"Water Temple MQ Triple Wall Torch Behind Gate Crate 3": "can_break_crate",
"Water Temple MQ GS Triple Wall Torch": "True"
}
}
]

View File

@ -3,35 +3,34 @@
"region_name": "Water Temple Lobby",
"dungeon": "Water Temple",
"events": {
# Child can access only falling platform room and L2 pots as the sole entrant into the temple
# Use Child_Water_Temple for cases where child assists after the water is lowered
"Child Water Temple": "is_child",
# Child can access only the falling platform room as the sole entrant into Water Temple.
# Use Child_Water_Temple for cases where child assists after the water is lowered.
# Use Raise_Water_Level to ensure the water level can be raised if it were to be lowered.
"Raise Water Level": "
(is_adult and (Hookshot or Hover_Boots or Bow)) or
(has_fire_source_with_torch and can_use_projectile)"
# Ensure that the water level can be raised if it were to be lowered.
},
"exits": {
"Lake Hylia": "True",
"Water Temple Highest Water Level": "Raise_Water_Level",
"Water Temple Dive": "
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and
((logic_water_temple_torch_longshot and can_use(Longshot)) or can_use(Iron_Boots))"
}
},
{
"region_name": "Water Temple Highest Water Level",
"dungeon": "Water Temple",
"events": {
"Water Temple Clear": "Boss_Key_Water_Temple and can_use(Longshot)"
},
"locations": {
"Morpha": "Boss_Key_Water_Temple and can_use(Longshot)",
"Water Temple Morpha Heart": "Boss_Key_Water_Temple and can_use(Longshot)",
"Water Temple Main Room L2 Pot 1": "
at('Water Temple Lowered Water Levels', True) or can_use(Boomerang) or
((can_use(Iron_Boots) or (Progressive_Scale, 2)) and
(can_use(Bow) or can_use(Hookshot) or can_use(Slingshot)) and
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements))",
"Water Temple Main Room L2 Pot 2": "
at('Water Temple Lowered Water Levels', True) or can_use(Boomerang) or
((can_use(Iron_Boots) or (Progressive_Scale, 2)) and
(can_use(Bow) or can_use(Hookshot) or can_use(Slingshot)) and
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements))",
"Fairy Pot": "has_bottle and can_use(Longshot)"
},
"exits": {
"Water Temple Falling Platform Room": "(Small_Key_Water_Temple, 4)"
"Lake Hylia": "True",
"Water Temple Dive": "
is_adult and (Zora_Tunic or logic_fewer_tunic_requirements) and
((logic_water_temple_torch_longshot and Longshot) or Iron_Boots)",
"Water Temple Falling Platform Room": "Raise_Water_Level and (Small_Key_Water_Temple, 4)",
"Water Temple Boss Door": "can_use(Longshot)"
}
},
{
@ -39,65 +38,81 @@
"dungeon": "Water Temple",
"locations": {
"Water Temple Map Chest": "Raise_Water_Level",
"Water Temple Compass Chest": "
(can_play(Zeldas_Lullaby) or Iron_Boots) and can_use(Hookshot)",
"Water Temple Torches Chest": "
(Bow or can_use(Dins_Fire) or
(Child_Water_Temple and Sticks and Kokiri_Sword and Magic_Meter)) and
can_play(Zeldas_Lullaby)",
"Water Temple Central Bow Target Chest": "
Progressive_Strength_Upgrade and can_play(Zeldas_Lullaby) and
((Bow and (logic_water_central_bow or Hover_Boots or can_use(Longshot))) or
(logic_water_central_bow and Child_Water_Temple and Slingshot and at('Water Temple Middle Water Level', True)))",
"Water Temple GS Behind Gate": "
(can_use(Hookshot) or can_use(Hover_Boots)) and
has_explosives and can_play(Zeldas_Lullaby) and
(can_use(Iron_Boots) or can_dive)",
"Water Temple GS Central Pillar": "
can_play(Zeldas_Lullaby) and
(((can_use(Longshot) or (logic_water_central_gs_fw and can_use(Hookshot) and can_use(Farores_Wind))) and
((Small_Key_Water_Temple, 5) or can_use(Bow) or can_use(Dins_Fire))) or
(logic_water_central_gs_irons and can_use(Hookshot) and can_use(Iron_Boots) and
(can_use(Bow) or can_use(Dins_Fire))) or
(logic_water_central_gs_fw and Child_Water_Temple and Boomerang and can_use(Farores_Wind) and
(Sticks or can_use(Dins_Fire) or
((Small_Key_Water_Temple, 5) and (can_use(Hover_Boots) or can_use(Bow))))))"
"Water Temple Compass Chest": "(can_play(Zeldas_Lullaby) or Iron_Boots) and Hookshot",
"Water Temple L1 Torch Pot 1": "(Iron_Boots and Hookshot) or can_play(Zeldas_Lullaby)",
"Water Temple L1 Torch Pot 2": "(Iron_Boots and Hookshot) or can_play(Zeldas_Lullaby)",
"Water Temple Near Compass Pot 1": "(can_play(Zeldas_Lullaby) or Iron_Boots) and Hookshot",
"Water Temple Near Compass Pot 2": "(can_play(Zeldas_Lullaby) or Iron_Boots) and Hookshot",
"Water Temple Near Compass Pot 3": "(can_play(Zeldas_Lullaby) or Iron_Boots) and Hookshot"
},
"exits": {
"Water Temple Cracked Wall": "
can_play(Zeldas_Lullaby) and (can_use(Hookshot) or can_use(Hover_Boots)) and
(logic_water_cracked_wall_nothing or (logic_water_cracked_wall_hovers and can_use(Hover_Boots)))",
"Water Temple Middle Water Level": "
(Bow or can_use(Dins_Fire) or
((Small_Key_Water_Temple, 5) and can_use(Hookshot)) or
(Child_Water_Temple and Sticks)) and
can_play(Zeldas_Lullaby)",
"Water Temple Lowered Water Levels": "can_play(Zeldas_Lullaby)",
"Water Temple North Basement": "
(Small_Key_Water_Temple, 4) and
(can_use(Longshot) or (logic_water_boss_key_region and can_use(Hover_Boots))) and
(can_use(Iron_Boots) or can_play(Zeldas_Lullaby))",
"Water Temple Dragon Statue": "
can_play(Zeldas_Lullaby) and Progressive_Strength_Upgrade and
((Iron_Boots and can_use(Hookshot)) or
(logic_water_dragon_adult and (has_bombchus or can_use(Bow) or can_use(Hookshot)) and (can_dive or Iron_Boots)) or
(logic_water_dragon_child and Child_Water_Temple and (has_bombchus or Slingshot or Boomerang) and can_dive))"
(Iron_Boots or can_play(Zeldas_Lullaby)) and
(Longshot or (logic_water_boss_key_region and Hover_Boots)) and
(Small_Key_Water_Temple, 4)"
}
},
{
"region_name": "Water Temple North Basement",
"region_name": "Water Temple Lowered Water Levels",
"dungeon": "Water Temple",
"locations": {
"Water Temple Boss Key Chest": "
(Small_Key_Water_Temple, 5) and
(logic_water_bk_jump_dive or can_use(Iron_Boots)) and
(logic_water_north_basement_ledge_jump or (has_explosives and Progressive_Strength_Upgrade) or Hover_Boots)",
"Water Temple GS Near Boss Key Chest": "True",
# Longshot just reaches without the need to actually go near,
# Otherwise you have hovers and just hover over and collect with a jump slash
"Fairy Pot": "
has_bottle and (Small_Key_Water_Temple, 5) and
(logic_water_bk_jump_dive or can_use(Iron_Boots)) and
(logic_water_north_basement_ledge_jump or (has_explosives and Progressive_Strength_Upgrade) or Hover_Boots)"
"Water Temple Torches Chest": "
Bow or can_use(Dins_Fire) or
(Child_Water_Temple and Sticks and Kokiri_Sword and Magic_Meter)",
"Water Temple GS Central Pillar": "
((Longshot or (logic_water_central_gs_fw and Hookshot and can_use(Farores_Wind))) and
((Small_Key_Water_Temple, 5) or Bow or can_use(Dins_Fire))) or
(logic_water_central_gs_irons and Hookshot and Iron_Boots and
(Bow or can_use(Dins_Fire))) or
(logic_water_central_gs_fw and Child_Water_Temple and Boomerang and can_use(Farores_Wind) and
Raise_Water_Level and ((Small_Key_Water_Temple, 5) or Sticks or can_use(Dins_Fire)))"
},
"exits": {
"Water Temple South Basement": "
has_explosives and (Iron_Boots or can_dive) and (Hookshot or Hover_Boots)",
"Water Temple Middle Water Level": "
Bow or can_use(Dins_Fire) or (Child_Water_Temple and Sticks) or
((Small_Key_Water_Temple, 5) and Hookshot)",
"Water Temple Cracked Wall": "
Raise_Water_Level and
(logic_water_cracked_wall_nothing or (logic_water_cracked_wall_hovers and Hover_Boots))",
"Water Temple Central Bow Target": "
Progressive_Strength_Upgrade and Bow and
(logic_water_central_bow or Hover_Boots or Longshot)",
"Water Temple Dragon Statue": "
Progressive_Strength_Upgrade and
((Iron_Boots and Hookshot) or
(logic_water_dragon_adult and
(has_bombchus or Bow or Hookshot) and (can_dive or Iron_Boots)) or
(logic_water_dragon_child and Child_Water_Temple and
(has_bombchus or Slingshot or Boomerang) and can_dive))"
}
},
{
"region_name": "Water Temple South Basement",
"dungeon": "Water Temple",
"locations": {
"Water Temple Behind Gate Pot 1": "True",
"Water Temple Behind Gate Pot 2": "True",
"Water Temple Behind Gate Pot 3": "True",
"Water Temple Behind Gate Pot 4": "True",
"Water Temple GS Behind Gate": "True"
}
},
{
"region_name": "Water Temple Middle Water Level",
"dungeon": "Water Temple",
"locations": {
"Water Temple Central Pillar Chest": "
((Small_Key_Water_Temple, 5) or Bow or can_use(Dins_Fire)) and
Iron_Boots and Zora_Tunic and Hookshot"
},
"exits": {
"Water Temple Cracked Wall": "True",
"Water Temple Central Bow Target": "
Progressive_Strength_Upgrade and
logic_water_central_bow and Child_Water_Temple and Slingshot"
}
},
{
@ -108,22 +123,38 @@
}
},
{
"region_name": "Water Temple Dragon Statue",
"region_name": "Water Temple Central Bow Target",
"dungeon": "Water Temple",
"locations": {
"Water Temple Dragon Chest": "True"
"Water Temple Central Bow Target Chest": "True",
"Water Temple Central Bow Target Pot 1": "True",
"Water Temple Central Bow Target Pot 2": "True"
}
},
{
"region_name": "Water Temple Middle Water Level",
"region_name": "Water Temple North Basement",
"dungeon": "Water Temple",
"locations": {
"Water Temple Central Pillar Chest": "
can_use(Iron_Boots) and can_use(Zora_Tunic) and can_use(Hookshot) and
((Small_Key_Water_Temple, 5) or can_use(Bow) or can_use(Dins_Fire))"
"Water Temple North Basement Block Puzzle Pot 1": "True",
"Water Temple North Basement Block Puzzle Pot 2": "True",
# Longshot reaches without the need to actually go near
# Otherwise you have Hovers and can you hover over and collect with a jumpslash
"Water Temple GS Near Boss Key Chest": "True"
},
"exits": {
"Water Temple Cracked Wall": "True"
"Water Temple Boss Key Chest Room": "
(Small_Key_Water_Temple, 5) and
(logic_water_bk_jump_dive or Iron_Boots) and
(logic_water_north_basement_ledge_jump or Hover_Boots or
(has_explosives and Progressive_Strength_Upgrade))"
}
},
{
"region_name": "Water Temple Boss Key Chest Room",
"dungeon": "Water Temple",
"locations": {
"Water Temple Boss Key Chest": "True",
"Fairy Pot": "has_bottle"
}
},
{
@ -136,7 +167,7 @@
(logic_water_falling_platform_gs_boomerang and can_use(Boomerang))"
},
"exits": {
"Water Temple Dark Link Region": "(Small_Key_Water_Temple, 5) and can_use(Hookshot)"
"Water Temple Dark Link Region": "can_use(Hookshot) and (Small_Key_Water_Temple, 5)"
}
},
{
@ -144,19 +175,39 @@
"dungeon": "Water Temple",
"locations": {
"Water Temple Longshot Chest": "True",
"Water Temple River Chest": "can_play(Song_of_Time) and Bow",
"Water Temple Like Like Pot 1": "True",
"Water Temple Like Like Pot 2": "True"
},
"exits": {
"Water Temple River": "can_play(Song_of_Time)"
}
},
{
"region_name": "Water Temple River",
"dungeon": "Water Temple",
"locations": {
"Water Temple River Chest": "Bow",
"Water Temple River Recovery Heart 1": "True",
"Water Temple River Recovery Heart 2": "True",
"Water Temple River Recovery Heart 3": "True",
"Water Temple River Recovery Heart 4": "True",
"Water Temple River Pot 1": "True",
"Water Temple GS River": "
can_play(Song_of_Time) and
((Iron_Boots and (can_use(Zora_Tunic) or logic_fewer_tunic_requirements)) or
(logic_water_river_gs and can_use(Longshot) and (Bow or has_bombchus)))",
"Fairy Pot":
"has_bottle and can_play(Song_of_Time)"
(Iron_Boots and (Zora_Tunic or logic_fewer_tunic_requirements)) or
(logic_water_river_gs and Longshot and (Bow or has_bombchus))",
"Fairy Pot": "has_bottle"
},
"exits": {
"Water Temple Dragon Statue": "
(can_use(Zora_Tunic) or logic_fewer_tunic_requirements) and
can_play(Song_of_Time) and Bow and
Bow and (Zora_Tunic or logic_fewer_tunic_requirements) and
(Iron_Boots or logic_water_dragon_jump_dive or logic_water_dragon_adult)"
}
},
{
"region_name": "Water Temple Dragon Statue",
"dungeon": "Water Temple",
"locations": {
"Water Temple Dragon Chest": "True"
}
}
]

Binary file not shown.

View File

@ -0,0 +1,3 @@
# To omit a track from shuffled music, list the filename of its
# .meta file below. One per line
# Lines that begin with # are comments and not parsed

File diff suppressed because it is too large Load Diff

View File

@ -1,196 +1,256 @@
{
"ADULT_INIT_ITEMS": "03481D54",
"ADULT_VALID_ITEMS": "03481D5C",
"AP_PLAYER_NAME": "03480834",
"AUDIO_THREAD_INFO": "03482FB0",
"AUDIO_THREAD_INFO_MEM_SIZE": "03482FCC",
"AUDIO_THREAD_INFO_MEM_START": "03482FC8",
"AUDIO_THREAD_MEM_START": "0348F330",
"BIG_POE_COUNT": "03480CEE",
"BOMBCHUS_IN_LOGIC": "03480CBC",
"CFG_A_BUTTON_COLOR": "03480854",
"CFG_A_NOTE_COLOR": "03480872",
"CFG_BOMBCHU_TRAIL_INNER_COLOR": "03480884",
"CFG_BOMBCHU_TRAIL_OUTER_COLOR": "03480887",
"CFG_BOOM_TRAIL_INNER_COLOR": "0348087E",
"CFG_BOOM_TRAIL_OUTER_COLOR": "03480881",
"CFG_B_BUTTON_COLOR": "0348085A",
"CFG_C_BUTTON_COLOR": "03480860",
"CFG_C_NOTE_COLOR": "03480878",
"CFG_DAMAGE_MULTIPLYER": "03482CA0",
"CFG_DISPLAY_DPAD": "0348088A",
"CFG_HEART_COLOR": "0348084E",
"CFG_MAGIC_COLOR": "03480848",
"CFG_RAINBOW_BOMBCHU_TRAIL_INNER_ENABLED": "0348088F",
"CFG_RAINBOW_BOMBCHU_TRAIL_OUTER_ENABLED": "03480890",
"CFG_RAINBOW_BOOM_TRAIL_INNER_ENABLED": "0348088D",
"CFG_RAINBOW_BOOM_TRAIL_OUTER_ENABLED": "0348088E",
"CFG_RAINBOW_NAVI_ENEMY_INNER_ENABLED": "03480893",
"CFG_RAINBOW_NAVI_ENEMY_OUTER_ENABLED": "03480894",
"CFG_RAINBOW_NAVI_IDLE_INNER_ENABLED": "03480891",
"CFG_RAINBOW_NAVI_IDLE_OUTER_ENABLED": "03480892",
"CFG_RAINBOW_NAVI_NPC_INNER_ENABLED": "03480895",
"CFG_RAINBOW_NAVI_NPC_OUTER_ENABLED": "03480896",
"CFG_RAINBOW_NAVI_PROP_INNER_ENABLED": "03480897",
"CFG_RAINBOW_NAVI_PROP_OUTER_ENABLED": "03480898",
"CFG_RAINBOW_SWORD_INNER_ENABLED": "0348088B",
"CFG_RAINBOW_SWORD_OUTER_ENABLED": "0348088C",
"CFG_SHOP_CURSOR_COLOR": "0348086C",
"CFG_TEXT_CURSOR_COLOR": "03480866",
"CHAIN_HBA_REWARDS": "03483940",
"CHEST_SIZE_MATCH_CONTENTS": "03482704",
"COMPLETE_MASK_QUEST": "0348B5A5",
"ADULT_INIT_ITEMS": "03482174",
"ADULT_VALID_ITEMS": "0348217C",
"APPLY_BONK_DAMAGE": "0348334C",
"AP_PLAYER_NAME": "03480839",
"AUDIO_THREAD_INFO": "034836FC",
"AUDIO_THREAD_INFO_MEM_SIZE": "0348371C",
"AUDIO_THREAD_INFO_MEM_START": "03483718",
"AUDIO_THREAD_MEM_START": "0349F3B0",
"AUTO_TRACKER_CONTEXT": "03480D7C",
"AUTO_TRACKER_VERSION": "03480D7C",
"BIG_POE_COUNT": "03480EAD",
"BOMBCHUS_IN_LOGIC": "03480D5C",
"BONK_LAST_FRAME": "03483298",
"CFG_A_BUTTON_COLOR": "0348085C",
"CFG_A_NOTE_COLOR": "0348087A",
"CFG_BOMBCHU_TRAIL_INNER_COLOR": "0348088C",
"CFG_BOMBCHU_TRAIL_OUTER_COLOR": "0348088F",
"CFG_BONK_DAMAGE": "03483290",
"CFG_BOOM_TRAIL_INNER_COLOR": "03480886",
"CFG_BOOM_TRAIL_OUTER_COLOR": "03480889",
"CFG_B_BUTTON_COLOR": "03480862",
"CFG_CUSTOM_MESSAGE_1": "034808A3",
"CFG_CUSTOM_MESSAGE_2": "034808C3",
"CFG_C_BUTTON_COLOR": "03480868",
"CFG_C_NOTE_COLOR": "03480880",
"CFG_DAMAGE_MULTIPLYER": "03483220",
"CFG_DEADLY_BONKS": "0348328C",
"CFG_DISPLAY_DPAD": "03480892",
"CFG_DPAD_DUNGEON_INFO_ENABLE": "034808A1",
"CFG_DUNGEON_INFO_ENABLE": "03480D80",
"CFG_DUNGEON_INFO_MQ_ENABLE": "03480D84",
"CFG_DUNGEON_INFO_MQ_NEED_MAP": "03480D88",
"CFG_DUNGEON_INFO_REWARD_ENABLE": "03480D8C",
"CFG_DUNGEON_INFO_REWARD_NEED_ALTAR": "03480D94",
"CFG_DUNGEON_INFO_REWARD_NEED_COMPASS": "03480D90",
"CFG_DUNGEON_INFO_REWARD_SUMMARY_ENABLE": "03480D98",
"CFG_DUNGEON_IS_MQ": "03480DAA",
"CFG_DUNGEON_REWARDS": "03480D9C",
"CFG_DUNGEON_REWARD_AREAS": "03480DD0",
"CFG_FILE_SELECT_HASH": "03480834",
"CFG_HEART_COLOR": "03480856",
"CFG_MAGIC_COLOR": "03480850",
"CFG_RAINBOW_BOMBCHU_TRAIL_INNER_ENABLED": "03480897",
"CFG_RAINBOW_BOMBCHU_TRAIL_OUTER_ENABLED": "03480898",
"CFG_RAINBOW_BOOM_TRAIL_INNER_ENABLED": "03480895",
"CFG_RAINBOW_BOOM_TRAIL_OUTER_ENABLED": "03480896",
"CFG_RAINBOW_NAVI_ENEMY_INNER_ENABLED": "0348089B",
"CFG_RAINBOW_NAVI_ENEMY_OUTER_ENABLED": "0348089C",
"CFG_RAINBOW_NAVI_IDLE_INNER_ENABLED": "03480899",
"CFG_RAINBOW_NAVI_IDLE_OUTER_ENABLED": "0348089A",
"CFG_RAINBOW_NAVI_NPC_INNER_ENABLED": "0348089D",
"CFG_RAINBOW_NAVI_NPC_OUTER_ENABLED": "0348089E",
"CFG_RAINBOW_NAVI_PROP_INNER_ENABLED": "0348089F",
"CFG_RAINBOW_NAVI_PROP_OUTER_ENABLED": "034808A0",
"CFG_RAINBOW_SWORD_INNER_ENABLED": "03480893",
"CFG_RAINBOW_SWORD_OUTER_ENABLED": "03480894",
"CFG_SHOP_CURSOR_COLOR": "03480874",
"CFG_SHOW_SETTING_INFO": "034808A2",
"CFG_TEXT_CURSOR_COLOR": "0348086E",
"CHAIN_HBA_REWARDS": "03484090",
"CHECK_FOR_BONK_CANCEL": "034832FC",
"CHECK_ROOM_MESH_TYPE": "0348341C",
"CHEST_LENS_ONLY": "03482B4C",
"CHEST_SIZE_MATCH_CONTENTS": "034948D8",
"CHEST_SIZE_TEXTURE": "034948D4",
"CHEST_TEXTURE_MATCH_CONTENTS": "034948DC",
"COMPLETE_MASK_QUEST": "0349492C",
"COOP_CONTEXT": "03480020",
"COOP_VERSION": "03480020",
"COSMETIC_CONTEXT": "03480844",
"COSMETIC_FORMAT_VERSION": "03480844",
"CURRENT_GROTTO_ID": "03482E72",
"DEATH_LINK": "0348002A",
"DEBUG_OFFSET": "03482890",
"DISABLE_TIMERS": "03480CDC",
"DPAD_TEXTURE": "0348DB28",
"DUNGEONS_SHUFFLED": "03480CDD",
"DUNGEON_IS_MQ_ADDRESS": "03480CE0",
"DUNGEON_REWARDS_ADDRESS": "03480CE4",
"ENHANCE_MAP_COMPASS": "03480CE8",
"EXTENDED_OBJECT_TABLE": "03480C9C",
"EXTERN_DAMAGE_MULTIPLYER": "03482CA1",
"FAST_BUNNY_HOOD_ENABLED": "03480CDF",
"FAST_CHESTS": "03480CD6",
"FONT_TEXTURE": "0348C660",
"FREE_SCARECROW_ENABLED": "03480CCC",
"GANON_BOSS_KEY_CONDITION": "0348B570",
"GANON_BOSS_KEY_CONDITION_COUNT": "0348B56E",
"GET_CHEST_OVERRIDE_WRAPPER": "03482708",
"GET_ITEM_TRIGGERED": "03481420",
"GOSSIP_HINT_CONDITION": "03480CC8",
"GROTTO_EXIT_LIST": "03482E30",
"GROTTO_LOAD_TABLE": "03482DAC",
"COSMETIC_CONTEXT": "0348084C",
"COSMETIC_FORMAT_VERSION": "0348084C",
"CURRENT_GROTTO_ID": "034835BE",
"CURR_ACTOR_SPAWN_INDEX": "0348448C",
"DEATH_LINK": "0348002B",
"DEBUG_OFFSET": "03482E10",
"DISABLE_TIMERS": "03480D71",
"DPAD_TEXTURE": "034993A8",
"DUNGEONS_SHUFFLED": "03480D72",
"DUNGEON_IS_MQ_ADDRESS": "03480E9F",
"DUNGEON_REWARDS_ADDRESS": "03480EA3",
"ENHANCE_MAP_COMPASS": "03480EA7",
"EXTENDED_OBJECT_TABLE": "03480D3C",
"EXTERN_DAMAGE_MULTIPLYER": "03483221",
"FAST_BUNNY_HOOD_ENABLED": "03480D74",
"FAST_CHESTS": "03480D6B",
"FIX_BROKEN_DROPS": "03480D75",
"FONT_TEXTURE": "03497EE0",
"FREE_SCARECROW_ENABLED": "03480D64",
"GANON_BOSS_KEY_CONDITION": "034948E4",
"GANON_BOSS_KEY_CONDITION_COUNT": "034948E2",
"GET_CHEST_OVERRIDE_WRAPPER": "03482B50",
"GET_ITEM_TRIGGERED": "0348183C",
"GILDED_CHEST_BASE_TEXTURE": "0349BBA8",
"GILDED_CHEST_FRONT_TEXTURE": "0349ABA8",
"GOSSIP_HINT_CONDITION": "03480D60",
"GROTTO_EXIT_LIST": "0348357C",
"GROTTO_LOAD_TABLE": "034834F8",
"HIDE_CHEST_WITH_INVERTED_LENS": "03482B98",
"INCOMING_ITEM": "03480028",
"INCOMING_PLAYER": "03480026",
"INITIAL_SAVE_DATA": "0348089C",
"JABU_ELEVATOR_ENABLE": "03480CD4",
"KAKARIKO_WEATHER_FORECAST": "0348B5C4",
"LACS_CONDITION": "03480CC4",
"LACS_CONDITION_COUNT": "03480CD2",
"MALON_GAVE_ICETRAP": "0348367C",
"MALON_TEXT_ID": "03480CDB",
"MAX_RUPEES": "0348B5A7",
"MOVED_ADULT_KING_ZORA": "03482FEC",
"NO_ESCAPE_SEQUENCE": "0348B56C",
"OCARINAS_SHUFFLED": "03480CD5",
"OPEN_FOREST": "03480CEC",
"OPEN_FOUNTAIN": "03480CED",
"OPEN_KAKARIKO": "0348B5A6",
"INITIAL_SAVE_DATA": "0348093C",
"JABU_ELEVATOR_ENABLE": "03480D68",
"KAKARIKO_WEATHER_FORECAST": "03494958",
"KING_DODONGO_BONKS": "034833E8",
"LACS_CONDITION": "03480DBC",
"LACS_CONDITION_COUNT": "03480DC2",
"MALON_GAVE_ICETRAP": "03483DCC",
"MALON_TEXT_ID": "03480D70",
"MAX_RUPEES": "0349492E",
"MOVED_ADULT_KING_ZORA": "0348373C",
"MW_SEND_OWN_ITEMS": "0348002A",
"NO_COLLECTIBLE_HEARTS": "03480D6A",
"NO_ESCAPE_SEQUENCE": "034948E1",
"OCARINAS_SHUFFLED": "03480D69",
"OPEN_FOREST": "03480EAB",
"OPEN_FOUNTAIN": "03480EAC",
"OPEN_KAKARIKO": "0349492D",
"OUTGOING_ITEM": "03480030",
"OUTGOING_KEY": "0348002C",
"OUTGOING_PLAYER": "03480032",
"OVERWORLD_SHUFFLED": "03480CDE",
"PAYLOAD_END": "0348F330",
"OVERWORLD_SHUFFLED": "03480D73",
"PAYLOAD_START": "03480000",
"PLAYED_WARP_SONG": "03481224",
"PLANDOMIZER_USED": "03480D77",
"PLAYED_WARP_SONG": "03481640",
"PLAYER_ID": "03480024",
"PLAYER_NAMES": "03480034",
"PLAYER_NAME_ID": "03480025",
"RAINBOW_BRIDGE_CONDITION": "03480CC0",
"RAINBOW_BRIDGE_COUNT": "03480CD0",
"POTCRATE_TEXTURES_MATCH_CONTENTS": "03480D78",
"RAINBOW_BRIDGE_CONDITION": "03480DB8",
"RAINBOW_BRIDGE_COUNT": "03480DC0",
"RANDOMIZER_RNG_SEED": "0349493C",
"RANDO_CONTEXT": "03480000",
"SHOP_SLOTS": "03480CEF",
"SHOW_DUNGEON_REWARDS": "03480CE9",
"SHUFFLE_BEANS": "03482D08",
"SHUFFLE_CARPET_SALESMAN": "034839F8",
"SHUFFLE_COWS": "03480CD7",
"SHUFFLE_MEDIGORON": "03483A54",
"SHUFFLE_SCRUBS": "03480CEB",
"SMALL_KEY_SHUFFLE": "03480CEA",
"SONGS_AS_ITEMS": "03480CD8",
"SOS_ITEM_GIVEN": "034814EC",
"SPEED_MULTIPLIER": "03482750",
"START_TWINROVA_FIGHT": "0348306C",
"TIME_TRAVEL_SAVED_EQUIPS": "03481A78",
"TRIFORCE_ICON_TEXTURE": "0348E328",
"TWINROVA_ACTION_TIMER": "03483070",
"WINDMILL_SONG_ID": "03480CD9",
"WINDMILL_TEXT_ID": "03480CDA",
"a_button": "0348B530",
"a_note_b": "0348B51C",
"a_note_font_glow_base": "0348B504",
"a_note_font_glow_max": "0348B500",
"a_note_g": "0348B520",
"a_note_glow_base": "0348B50C",
"a_note_glow_max": "0348B508",
"a_note_r": "0348B524",
"active_item_action_id": "0348B588",
"active_item_fast_chest": "0348B578",
"active_item_graphic_id": "0348B57C",
"active_item_object_id": "0348B580",
"active_item_row": "0348B58C",
"active_item_text_id": "0348B584",
"active_override": "0348B594",
"active_override_is_outgoing": "0348B590",
"b_button": "0348B52C",
"beating_dd": "0348B538",
"beating_no_dd": "0348B540",
"c_button": "0348B528",
"c_note_b": "0348B510",
"c_note_font_glow_base": "0348B4F4",
"c_note_font_glow_max": "0348B4F0",
"c_note_g": "0348B514",
"c_note_glow_base": "0348B4FC",
"c_note_glow_max": "0348B4F8",
"c_note_r": "0348B518",
"cfg_dungeon_info_enable": "0348B4BC",
"cfg_dungeon_info_mq_enable": "0348B560",
"cfg_dungeon_info_mq_need_map": "0348B55C",
"cfg_dungeon_info_reward_enable": "0348B4B8",
"cfg_dungeon_info_reward_need_altar": "0348B554",
"cfg_dungeon_info_reward_need_compass": "0348B558",
"cfg_dungeon_is_mq": "0348B5C8",
"cfg_dungeon_rewards": "0348A274",
"cfg_file_select_hash": "0348B568",
"cfg_item_overrides": "0348B61C",
"defaultDDHeart": "0348B544",
"defaultHeart": "0348B54C",
"dpad_sprite": "0348A428",
"dummy_actor": "0348B59C",
"dungeon_count": "0348B4C0",
"dungeons": "0348A298",
"empty_dlist": "0348B4D8",
"extern_ctxt": "0348A334",
"font_sprite": "0348A438",
"freecam_modes": "03489FF0",
"hash_sprites": "0348B4CC",
"hash_symbols": "0348A348",
"heap_next": "0348B5C0",
"heart_sprite": "0348A3C8",
"icon_sprites": "0348A1B4",
"item_digit_sprite": "0348A3E8",
"item_overrides_count": "0348B5A0",
"item_table": "0348A4B0",
"items_sprite": "0348A458",
"key_rupee_clock_sprite": "0348A3F8",
"last_fog_distance": "0348B4C4",
"linkhead_skull_sprite": "0348A3D8",
"medal_colors": "0348A284",
"medals_sprite": "0348A468",
"normal_dd": "0348B534",
"normal_no_dd": "0348B53C",
"num_to_bits": "0348A388",
"object_slots": "0348C61C",
"pending_freezes": "0348B5A4",
"pending_item_queue": "0348B604",
"quest_items_sprite": "0348A448",
"rupee_colors": "0348A1C0",
"satisified_pending_frames": "0348B574",
"scene_fog_distance": "0348B4C8",
"setup_db": "0348A488",
"song_note_sprite": "0348A408",
"stones_sprite": "0348A478",
"text_cursor_border_base": "0348B4E4",
"text_cursor_border_max": "0348B4E0",
"text_cursor_inner_base": "0348B4EC",
"text_cursor_inner_max": "0348B4E8",
"triforce_hunt_enabled": "0348B5B4",
"triforce_pieces_requied": "0348B552",
"triforce_sprite": "0348A418"
"RNG_SEED_INT": "034948CC",
"SET_BONK_FLAG": "034832D0",
"SHOP_SLOTS": "03480EAE",
"SHOW_CHEST_WITH_INVERTED_LENS": "03482C10",
"SHOW_DUNGEON_REWARDS": "03480EA8",
"SHUFFLE_BEANS": "03483454",
"SHUFFLE_CARPET_SALESMAN": "03484148",
"SHUFFLE_COWS": "03480D6C",
"SHUFFLE_MEDIGORON": "034841A4",
"SHUFFLE_SCRUBS": "03480EAA",
"SILVER_CHEST_BASE_TEXTURE": "0349D3A8",
"SILVER_CHEST_FRONT_TEXTURE": "0349C3A8",
"SKULL_CHEST_BASE_TEXTURE": "0349EBA8",
"SKULL_CHEST_FRONT_TEXTURE": "0349DBA8",
"SMALL_KEY_SHUFFLE": "03480EA9",
"SONGS_AS_ITEMS": "03480D6D",
"SOS_ITEM_GIVEN": "03481908",
"SPECIAL_DEAL_COUNTS": "03480DC8",
"SPEED_MULTIPLIER": "03482CD0",
"SPOILER_AVAILABLE": "03480D76",
"START_TWINROVA_FIGHT": "034837BC",
"Sram_InitNewSave": "034948D0",
"TIME_STRING_TXT": "03480918",
"TIME_TRAVEL_SAVED_EQUIPS": "03481E98",
"TRIFORCE_HUNT_ENABLED": "03480DC4",
"TRIFORCE_ICON_TEXTURE": "03499BA8",
"TRIFORCE_PIECES_REQUIRED": "03480DC6",
"TWINROVA_ACTION_TIMER": "034837C0",
"VERSION_STRING_TXT": "034808E4",
"WINDMILL_SONG_ID": "03480D6E",
"WINDMILL_TEXT_ID": "03480D6F",
"WORLD_STRING_TXT": "03480908",
"a_button": "034948A0",
"a_note_b": "0349488C",
"a_note_font_glow_base": "03494874",
"a_note_font_glow_max": "03494870",
"a_note_g": "03494890",
"a_note_glow_base": "0349487C",
"a_note_glow_max": "03494878",
"a_note_r": "03494894",
"active_item_action_id": "0349490C",
"active_item_fast_chest": "034948FC",
"active_item_graphic_id": "03494900",
"active_item_object_id": "03494904",
"active_item_row": "03494910",
"active_item_text_id": "03494908",
"active_override": "03494918",
"active_override_is_outgoing": "03494914",
"adultSkeleton": "034945F4",
"adult_safe": "03494936",
"alt_overrides": "034949C8",
"b_button": "0349489C",
"beating_dd": "034948A8",
"beating_no_dd": "034948B0",
"c_button": "03494898",
"c_note_b": "03494880",
"c_note_font_glow_base": "03494864",
"c_note_font_glow_max": "03494860",
"c_note_g": "03494884",
"c_note_glow_base": "0349486C",
"c_note_glow_max": "03494868",
"c_note_r": "03494888",
"cfg_item_overrides": "03494E20",
"childSkeleton": "034944F8",
"child_safe": "03494935",
"collectible_mutex": "034948F0",
"collectible_override": "034948E8",
"collectible_override_flags": "034948F4",
"collectible_scene_flags_table": "03494BC8",
"curr_scene_setup": "03494940",
"defaultDDHeart": "034948B4",
"defaultHeart": "034948BC",
"dpad_sprite": "03491F88",
"drop_collectible_override_flag": "03494920",
"dummy_actor": "03494924",
"dungeon_count": "03494830",
"dungeons": "03491DD0",
"empty_dlist": "03494848",
"extern_ctxt": "03491E7C",
"font_sprite": "03491F98",
"freecam_modes": "03491A40",
"hash_sprites": "0349483C",
"hash_symbols": "03491E90",
"heap_next": "03494954",
"heart_sprite": "03491F28",
"icon_sprites": "03491C04",
"illegal_model": "03494938",
"item_digit_sprite": "03491F48",
"item_draw_table": "03492010",
"item_overrides_count": "03494928",
"item_table": "034930E8",
"items": "03491F10",
"items_sprite": "03491FB8",
"key_counts": "034930CC",
"key_rupee_clock_sprite": "03491F58",
"last_fog_distance": "03494834",
"linkhead_skull_sprite": "03491F38",
"medals": "03491DB8",
"medals_sprite": "03491FC8",
"missing_dlist": "03494934",
"normal_dd": "034948A4",
"normal_no_dd": "034948AC",
"num_override_flags": "034948F8",
"num_to_bits": "03491ED0",
"object_slots": "03497E20",
"outgoing_queue": "03494988",
"quest_items_sprite": "03491FA8",
"reward_rows": "03491DAC",
"rupee_colors": "03491C28",
"satisified_pending_frames": "034948FA",
"scene_fog_distance": "03494838",
"setup_db": "03491FE8",
"song_note_sprite": "03491F68",
"stones_sprite": "03491FD8",
"text_cursor_border_base": "03494854",
"text_cursor_border_max": "03494850",
"text_cursor_inner_base": "0349485C",
"text_cursor_inner_max": "03494858",
"text_height": "034948C4",
"text_width": "034948C8",
"texture_table": "034946F0",
"triforce_sprite": "03491F78"
}

View File

@ -75,7 +75,7 @@
"005E FF67 0000 0002 0000 0000 0000 03E7",
"005E 0190 0168 0079 0000 B555 0000 03E7",
"005E FE16 0320 FFDC 0000 CAAB 0000 03E7",
"012A FEC9 0320 FEC9 0000 E000 0000 2700",
"012A FEC9 031F FEC9 0000 E000 0000 2700",
"01A0 0117 0168 014D 0000 6000 0000 FFFF",
"000A 014D 0168 00FD 0000 20B6 0000 0823",
"000F 0000 0000 0000 0000 4000 0000 0FC5",
@ -2833,7 +2833,8 @@
"0163",
"00A4",
"0024",
"015C"
"015C",
"00B7"
],
"Actors": [
"003B 0F0B 0028 FA0A 0000 0000 0000 0006",
@ -3087,7 +3088,8 @@
"0036",
"001F",
"000D",
"0170"
"0170",
"00B7"
],
"Actors": [
"0125 06B1 019B FB22 0000 0000 0000 FF01",
@ -14895,7 +14897,7 @@
"0095 01C3 01ED 02A4 0000 C000 0000 0000",
"0037 0069 03FD 01F8 0000 671C 0000 0000",
"000A 018C 047F 0194 0000 4000 000D 8843",
"012A FF58 035C 0243 0000 505B 0000 0D00"
"012A FF58 035B 0243 0000 505B 0000 0D00"
]
},
{
@ -16847,7 +16849,7 @@
"0111 F7C2 0AF0 FD7A 0000 0000 0000 4C04",
"0111 F6F1 0AF0 0346 0000 0000 0000 4E12",
"0111 F713 0AF0 0323 0000 0000 0000 500B",
"012A F74F 0AF0 FC3A 0000 2000 0000 3900"
"012A F74F 0AEF FC3A 0000 2000 0000 3900"
]
},
{
@ -16930,7 +16932,7 @@
"0008 F77C 1293 01F4 0000 4000 0000 03F5",
"0008 F7F4 1293 017C 0000 4000 0000 03F5",
"012A F6AA 1130 FF00 0000 0000 0000 3C03",
"012A FA34 1130 012C 0000 2000 0000 3A00",
"012A FA34 112F 012C 0000 2000 0000 3A00",
"000A F77C 1248 017C 0000 E000 0000 5845"
]
},
@ -16999,7 +17001,7 @@
"005E 04C4 0CDA FFCE E38E 4000 0000 105F",
"0111 05D5 0AF0 0182 0000 0000 0000 5209",
"0111 05A5 0AF0 01BD 0000 0000 0000 5409",
"012A 04AF 0AF0 FF64 0000 2000 0000 3C20",
"012A 04AF 0AEF FF64 0000 2000 0000 3C20",
"01A0 04BA 0B7C 00A3 0000 E000 0000 FFFF",
"01A0 03E7 0ADC FE6E 0000 4000 0000 FFFF",
"01A0 0581 0AF0 FB68 0000 0000 0000 FFFF",
@ -20348,7 +20350,7 @@
"Icons": [
{
"Icon": 0,
"Count": 5,
"Count": 6,
"IconPoints": [
{
"Flag": 1,
@ -20374,6 +20376,11 @@
"Flag": 12,
"x": 47,
"y": -26
},
{
"Flag": 0,
"x": 48,
"y": -17
}
]
},
@ -20469,12 +20476,18 @@
{
"Icons": [
{
"Icon": -1,
"Count": 0,
"IconPoints": []
"Icon": 0,
"Count": 1,
"IconPoints": [
{
"Flag": 0,
"x": 71,
"y": 60
}
]
},
{
"Icon": 0,
"Icon": -1,
"Count": 0,
"IconPoints": []
},
@ -25694,7 +25707,7 @@
"00A5 F688 FFC1 FEED 0000 0000 0000 FFFF",
"00A5 F6DB FFC1 FEB1 0000 0000 0000 FFFF",
"00A5 F6E1 FFC1 FE1C 0000 0000 0000 FFFF",
"00A4 F688 FFC1 FE63 0000 0000 0000 FFFF",
"00A4 F67E FFC1 FE6B 0000 0000 0000 FFFF",
"000A F562 FFC1 FE64 0000 C000 0001 15E7"
]
},
@ -25755,7 +25768,7 @@
"0117 0DE6 FDE1 FA2E 0000 0000 0000 1FC1",
"0117 0D1F FE14 FC4D 0000 0000 0000 0141",
"0173 0FE1 FE20 FB35 0000 FFA6 0000 2181",
"0187 0D1E FDE1 FE2E 0000 0000 0000 1FFF",
"0187 0D1E FDE1 FE2E 0000 0000 0000 FFFF",
"00AE 0F8A FDE1 FB36 0000 0000 0000 0007",
"00AF 0EB8 FDE1 FCEE 0000 4000 0000 0103",
"00B1 0D1E FDE1 FC4E 0000 0000 0000 0000",
@ -25783,7 +25796,7 @@
"0090 0DAA FDE1 02D1 0000 8000 0000 7FFE",
"005E 0CEE FDE1 033E 0000 8000 0000 2400",
"005E 0D50 FDE1 033B 0000 8000 0000 2400",
"0187 0D1E FDE1 0260 0000 0000 0000 1FFF",
"0187 0D1E FDE1 0260 0000 0000 0000 FFFF",
"000A 0D22 FDE1 0375 0000 0000 0000 7843"
]
},
@ -26140,7 +26153,7 @@
"012F"
],
"Actors": [
"00A4 EF30 FAAD FE36 0000 8000 0000 FFFF",
"00A4 EF2E FAAD FDE2 0000 8000 0000 FFFF",
"0111 EE21 FAAD FCD5 0000 0000 0000 660B",
"0111 F03C FAAD FCD5 0000 0000 0000 680A",
"004C EE50 FAAD FE96 0000 216C 0000 FFFF",
@ -27437,7 +27450,8 @@
"0098",
"0024",
"00A4",
"0009"
"0009",
"00B7"
],
"Actors": [
"0090 F927 0000 FD1E 0000 4000 0000 7FFE",
@ -27517,7 +27531,7 @@
"00A5 0464 FFEC 0173 0000 C000 0000 FFFF",
"00A5 059D FFEC 0036 0000 C000 0000 FFFF",
"00A5 059D FFEC 0170 0000 C000 0000 FFFF",
"00A4 04FC FFF0 00D1 0000 C000 0000 FFFF",
"00A4 0500 FFF0 00D2 0000 C000 0000 FFFF",
"0015 0644 FFEC FFA8 0000 0000 0000 0211",
"000A 0524 FFEC 0079 0000 C000 0000 1802",
"00BE 062C 0000 FFA6 0000 C000 0000 2102"

Some files were not shown because too many files have changed in this diff Show More