Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2024-01-05 13:09:20 -06:00
53 changed files with 2624 additions and 582 deletions
-7
View File
@@ -10,7 +10,6 @@ except ImportError:
from Utils import output_path
from Rom import LocalRom, apply_rom_settings
from source.classes.SFX import output_song_data
from source.tools.BPS import bps_read_vlv
@@ -39,9 +38,6 @@ def adjust(args):
output_path.cached_path = args.outputpath
rom.write_to_file(output_path('%s.sfc' % outfilebase))
if args.shuffle_songinstruments:
output_song_data(rom, output_path('OR_SPCInstruments.txt'), outfilebase)
logger.info('Done. Enjoy.')
logger.debug('Total Time: %s', time.process_time() - start)
@@ -77,9 +73,6 @@ def patch(args):
output_path.cached_path = args.outputpath
rom.write_to_file(output_path('%s.sfc' % outfile_base))
if args.shuffle_songinstruments:
output_song_data(rom, output_path('OR_SPCInstruments.txt'), outfile_base)
logger.info('Done. Enjoy.')
logger.debug('Total Time: %s', time.process_time() - start)
+61 -11
View File
@@ -64,7 +64,6 @@ class World(object):
self.dark_world_light_cone = False
self.clock_mode = 'none'
self.rupoor_cost = 10
self.aga_randomness = True
self.lock_aga_door_in_escape = False
self.save_and_quit_from_boss = True
self.override_bomb_check = False
@@ -134,7 +133,7 @@ class World(object):
set_player_attr('can_access_trock_front', None)
set_player_attr('can_access_trock_big_chest', None)
set_player_attr('can_access_trock_middle', None)
set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic']
set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'hybridglitches', 'nologic']
or shuffle[player] in ['lean', 'swapped', 'crossed', 'insanity'])
set_player_attr('mapshuffle', False)
set_player_attr('compassshuffle', False)
@@ -170,7 +169,8 @@ class World(object):
set_player_attr('door_self_loops', False)
set_player_attr('door_type_mode', 'original')
set_player_attr('trap_door_mode', 'optional')
set_player_attr('key_logic_algorithm', 'default')
set_player_attr('key_logic_algorithm', 'partial')
set_player_attr('aga_randomness', True)
set_player_attr('shopsanity', False)
set_player_attr('mixed_travel', 'prevent')
@@ -565,7 +565,7 @@ class World(object):
if not sphere:
# ran out of places and did not finish yet, quit
if log_error:
missing_locations = ", ".join([x.name for x in prog_locations])
missing_locations = ", ".join([f'{x.name} (#{x.player})' for x in prog_locations])
logging.getLogger('').error(f'Cannot reach the following locations: {missing_locations}')
return False
@@ -600,9 +600,45 @@ class CollectionState(object):
self.opened_doors = {player: set() for player in range(1, parent.players + 1)}
self.dungeons_to_check = {player: defaultdict(dict) for player in range(1, parent.players + 1)}
self.dungeon_limits = None
self.placing_item = None
self.placing_items = None
# self.trace = None
def can_reach_from(self, spot, start, player=None):
old_state = self.copy()
# old_state.path = {old_state.world.get_region(start, player)}
old_state.stale[player] = False
old_state.reachable_regions[player] = dict()
old_state.blocked_connections[player] = dict()
rrp = old_state.reachable_regions[player]
bc = old_state.blocked_connections[player]
# init on first call - this can't be done on construction since the regions don't exist yet
start = self.world.get_region(start, player)
if start in self.reachable_regions[player]:
rrp[start] = self.reachable_regions[player][start]
for conn in start.exits:
bc[conn] = self.blocked_connections[player][conn]
else:
rrp[start] = CrystalBarrier.Orange
for conn in start.exits:
bc[conn] = CrystalBarrier.Orange
queue = deque(old_state.blocked_connections[player].items())
old_state.traverse_world(queue, rrp, bc, player)
if old_state.world.key_logic_algorithm[player] == 'default':
unresolved_events = [x for y in old_state.reachable_regions[player] for x in y.locations
if x.event and x.item and (x.item.smallkey or x.item.bigkey or x.item.advancement)
and x not in old_state.locations_checked and x.can_reach(old_state)]
unresolved_events = old_state._do_not_flood_the_keys(unresolved_events)
if len(unresolved_events) == 0:
old_state.check_key_doors_in_dungeons(rrp, player)
if self.world.get_region(spot, player) in rrp:
return True
else:
return False
def update_reachable_regions(self, player):
self.stale[player] = False
rrp = self.reachable_regions[player]
@@ -878,7 +914,7 @@ class CollectionState(object):
return door_candidates
door_candidates, skip = [], set()
if (state.world.accessibility[player] != 'locations' and remaining_keys == 0 and dungeon_name != 'Universal'
and state.placing_item and state.placing_item.name == small_key_name):
and state.placing_items and any(i.name == small_key_name and i.player == player for i in state.placing_items)):
key_logic = state.world.key_logic[player][dungeon_name]
for door, paired in key_logic.sm_doors.items():
if door.name in key_logic.door_rules:
@@ -923,7 +959,7 @@ class CollectionState(object):
player: defaultdict(dict, {name: copy.copy(checklist)
for name, checklist in self.dungeons_to_check[player].items()})
for player in range(1, self.world.players + 1)}
ret.placing_item = self.placing_item
ret.placing_items = self.placing_items
return ret
def apply_dungeon_exploration(self, rrp, player, dungeon_name, checklist):
@@ -1020,7 +1056,7 @@ class CollectionState(object):
# try to resolve a name
if resolution_hint == 'Location':
spot = self.world.get_location(spot, player)
elif resolution_hint in ['Entrance', 'OWEdge', 'OWTerrain', 'Ledge', 'Portal', 'Whirlpool', 'Mirror', 'Flute']:
elif resolution_hint in ['Entrance', 'OWEdge', 'OWTerrain', 'OpenTerrain', 'Ledge', 'OWG', 'Portal', 'Whirlpool', 'Mirror', 'Flute']:
spot = self.world.get_entrance(spot, player)
else:
# default to Region
@@ -1169,6 +1205,12 @@ class CollectionState(object):
def can_lift_rocks(self, player):
return self.has('Power Glove', player) or self.has('Titans Mitts', player)
def can_bomb_clip(self, region, player: int) -> bool:
return self.is_not_bunny(region, player) and self.has('Pegasus Boots', player) and self.can_use_bombs(player)
def can_dash_clip(self, region, player: int) -> bool:
return self.is_not_bunny(region, player) and self.has('Pegasus Boots', player)
def has_bottle(self, player):
return self.bottle_count(player) > 0
@@ -1300,7 +1342,9 @@ class CollectionState(object):
return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player))
def can_avoid_lasers(self, player):
return self.has('Mirror Shield', player) or self.has('Cane of Byrna', player) or self.has('Cape', player)
return (self.has('Mirror Shield', player) or
self.has('Cape', player) or
(self.has('Cane of Byrna', player) and self.world.difficulty_adjustments[player] not in ['hard', 'expert']))
def is_not_bunny(self, region, player):
return self.has_Pearl(player) or not region.can_cause_bunny(player)
@@ -1346,6 +1390,9 @@ class CollectionState(object):
def can_superbunny_mirror_with_sword(self, player):
return self.has_Mirror(player) and self.has_sword(player)
def can_bunny_pocket(self, player):
return self.has_Boots(player) and (self.has_Mirror(player) or self.has_bottle(player))
def collect(self, item, event=False, location=None):
if location:
self.locations_checked.add(location)
@@ -1555,6 +1602,9 @@ class Region(object):
return self.is_dark_world if self.world.mode[player] != 'inverted' else self.is_light_world
def is_outdoors(self):
return self.type in {RegionType.LightWorld, RegionType.DarkWorld}
def __str__(self):
return str(self.__unicode__())
@@ -1626,7 +1676,7 @@ class Entrance(object):
if region not in explored_regions:
explored_regions[region] = path
for exit in region.exits:
if exit.connected_region and (not ignore_ledges or exit.spot_type != 'Ledge') \
if exit.connected_region and (not ignore_ledges or exit.spot_type not in ['Ledge', 'OWG']) \
and exit.name not in ['Dig Game To Ledge Drop'] \
and exit.access_rule(state):
if exit.connected_region == destination:
@@ -3417,7 +3467,7 @@ er_mode = {"vanilla": 0, "simple": 1, "restricted": 2, "full": 3, "crossed": 4,
'lean': 9, "dungeonsfull": 7, "dungeonssimple": 6, "swapped": 10}
# byte 1: LLLW WSS? (logic, mode, sword)
logic_mode = {"noglitches": 0, "minorglitches": 1, "nologic": 2, "owglitches": 3, "majorglitches": 4}
logic_mode = {"noglitches": 0, "minorglitches": 1, "nologic": 2, "owglitches": 3, "majorglitches": 4, "hybridglitches": 5}
world_mode = {"open": 0, "standard": 1, "inverted": 2}
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
+18
View File
@@ -1,5 +1,23 @@
# Changelog
## 0.3.4.0
- \~Merged in some things from DR v1.4.0.0-v~
- Improved bunny-walking algorithm
- Improved multiworld balancing
- Implemented Hyrid Major Glitches logic (thanks Muffins/Espeon)
- Added sparkles to Bonk Drop locations for better visibility
- Some tweaks/improvements to Shuffle Song Instruments
- Replaced Save Settings on Exit with Settings on Load
- Added new button in GUI to export a Yaml file based on current settings
- Allow starting Aga-Defeated and Old-Man-Rescued in inventory
## 0.3.3.2
- \~Merged in DR v1.2.0.22~
- Added Shuffle Song Instruments as post-gen option
- Allow user to change and save output directory within the GUI
- Fixed issue with Smith not deleting on S+Q when no path is possible
- Fixed various MSU inaccuracies
## 0.3.3.1
- \~Merged in DR v1.2.0.21~
- Fixed issue with Old Man death spawning on Pyramid/Castle
+14 -4
View File
@@ -34,7 +34,9 @@ def parse_cli(argv, no_defaults=False):
parser.add_argument('--settingsfile', help="input json file of settings", type=str)
parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255))
parser.add_argument('--customizer', help='input yaml file for customizations', type=str)
parser.add_argument('--print_custom_yaml', help='print example yaml for current settings',
parser.add_argument('--print_template_yaml', help='print example yaml for current settings',
default=False, action="store_true")
parser.add_argument('--print_custom_yaml', help='print example plando yaml for current settings and placements',
default=False, action="store_true")
parser.add_argument('--mystery', dest="mystery", default=False, action="store_true")
@@ -94,6 +96,7 @@ def parse_cli(argv, no_defaults=False):
parser.add_argument('--teams', default=defval(1), type=lambda value: max(int(value), 1))
parser.add_argument('--settingsfile', dest="filename", help="input json file of settings", type=str)
parser.add_argument('--customizer', dest="customizer", help='input yaml file for customizations', type=str)
parser.add_argument('--print_template_yaml', dest="print_template_yaml", default=False, action="store_true")
parser.add_argument('--print_custom_yaml', dest="print_custom_yaml", default=False, action="store_true")
if player_num:
@@ -142,7 +145,7 @@ def parse_cli(argv, no_defaults=False):
'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle',
'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx', 'shuffle_songinstruments',
'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode',
'bonk_drops', 'trap_door_mode', 'key_logic_algorithm', 'door_self_loops']:
'bonk_drops', 'trap_door_mode', 'key_logic_algorithm', 'door_self_loops', 'aga_randomness']:
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
if player == 1:
setattr(ret, name, {1: value})
@@ -225,13 +228,14 @@ def parse_settings():
"intensity": 3,
"door_type_mode": "original",
"trap_door_mode": "optional",
"key_logic_algorithm": "default",
"key_logic_algorithm": "partial",
"decoupledoors": False,
"door_self_loops": False,
"experimental": False,
"dungeon_counters": "default",
"mixed_travel": "prevent",
"standardize_palettes": "standardize",
'aga_randomness': True,
"triforce_pool": 0,
"triforce_goal": 0,
@@ -355,7 +359,7 @@ def parse_settings():
},
"randomSprite": False,
"outputpath": os.path.join("."),
"saveonexit": "ask",
"settingsonload": "saved",
"outputname": "",
"startinventoryarray": {},
"notes": ""
@@ -367,6 +371,12 @@ def parse_settings():
# read saved settings file if it exists and set these
settings_path = os.path.join(".", "resources", "user", "settings.json")
settings = apply_settings_file(settings, settings_path)
if settings["settingsonload"] == "saved":
settings_path = os.path.join(".", "resources", "user", "saved.json")
settings = apply_settings_file(settings, settings_path)
elif settings["settingsonload"] == "lastused":
settings_path = os.path.join(".", "resources", "user", "last.json")
settings = apply_settings_file(settings, settings_path)
return settings
# Priority fallback is:
+19 -3
View File
@@ -7,7 +7,7 @@ from typing import DefaultDict, Dict, List
from itertools import chain
from BaseClasses import RegionType, Region, Door, DoorType, Sector, CrystalBarrier, DungeonInfo, dungeon_keys
from BaseClasses import PotFlags, LocationType, Direction
from BaseClasses import PotFlags, LocationType, Direction, KeyRuleType
from Doors import reset_portals
from Dungeons import dungeon_regions, region_starts, standard_starts, split_region_starts
from Dungeons import dungeon_bigs, dungeon_hints
@@ -261,8 +261,24 @@ def vanilla_key_logic(world, player):
world.key_logic[player][builder.name] = key_layout.key_logic
world.key_layout[player][builder.name] = key_layout
log_key_logic(builder.name, key_layout.key_logic)
# if world.shuffle[player] == 'vanilla' and world.accessibility[player] == 'items' and not world.retro[player] and not world.keydropshuffle[player]:
# validate_vanilla_key_logic(world, player)
# special adjustments for vanilla
if world.mode[player] != 'standard' and world.dropshuffle[player] == 'none':
# adjust hc doors
def adjust_hc_door(door_rule):
if door_rule.new_rules[KeyRuleType.WorstCase] == 3:
door_rule.new_rules[KeyRuleType.WorstCase] = 2
door_rule.small_key_num = 2
rules = world.key_logic[player]['Hyrule Castle'].door_rules
adjust_hc_door(rules['Sewers Secret Room Key Door S'])
adjust_hc_door(rules['Hyrule Dungeon Map Room Key Door S'])
adjust_hc_door(rules['Sewers Dark Cross Key Door N'])
# adjust pod front door
pod_front = world.key_logic[player]['Palace of Darkness'].door_rules['PoD Middle Cage N']
if pod_front.new_rules[KeyRuleType.WorstCase] == 6:
pod_front.new_rules[KeyRuleType.WorstCase] = 1
pod_front.small_key_num = 1
# gt logic? I'm unsure it needs adjusting
def validate_vanilla_reservation(dungeon, world, player):
+1 -1
View File
@@ -814,7 +814,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, must
# Keeps track of entrances that cannot be used to access each exit / cave
invalid_cave_connections = defaultdict(set)
# if world.logic[player] in ['owglitches', 'nologic']:
# if world.logic[player] in ['owglitches', 'hybridglitches', 'nologic']:
# import OverworldGlitchRules
# for entrance in OverworldGlitchRules.get_non_mandatory_exits(world, player):
# if entrance in must_be_exits:
+41 -11
View File
@@ -3,6 +3,7 @@ import collections
import itertools
import logging
import math
from collections import Counter
from contextlib import suppress
from BaseClasses import CollectionState, FillError, LocationType
@@ -71,13 +72,13 @@ def fill_dungeons_restrictive(world, shuffled_locations):
def fill_restrictive(world, base_state, locations, itempool, key_pool=None, single_player_placement=False,
vanilla=False):
def sweep_from_pool(placing_item=None):
def sweep_from_pool(placing_items=None):
new_state = base_state.copy()
for item in itempool:
new_state.collect(item, True)
new_state.placing_item = placing_item
new_state.placing_items = placing_items
new_state.sweep_for_events()
new_state.placing_item = None
new_state.placing_items = None
return new_state
unplaced_items = []
@@ -94,7 +95,7 @@ def fill_restrictive(world, base_state, locations, itempool, key_pool=None, sing
while any(player_items.values()) and locations:
items_to_place = [[itempool.remove(items[-1]), items.pop()][-1] for items in player_items.values() if items]
maximum_exploration_state = sweep_from_pool(placing_item=items_to_place[0])
maximum_exploration_state = sweep_from_pool(placing_items=items_to_place)
has_beaten_game = world.has_beaten_game(maximum_exploration_state)
for item_to_place in items_to_place:
@@ -174,6 +175,9 @@ def valid_key_placement(item, location, key_pool, collection_state, world):
if dungeon:
if dungeon.name not in item.name and (dungeon.name != 'Hyrule Castle' or 'Escape' not in item.name):
return True
# Small key and big key in Swamp and Hera are placed without logic
if world.logic[item.player] == 'hybridglitches' and dungeon.name in ['Tower of Hera', 'Swamp Palace'] and dungeon.name in item.name:
return True
key_logic = world.key_logic[item.player][dungeon.name]
unplaced_keys = len([x for x in key_pool if x.name == key_logic.small_key_name and x.player == item.player])
prize_loc = None
@@ -419,7 +423,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
# fill in gtower locations with trash first
for player in range(1, world.players + 1):
if (not gftower_trash or not world.ganonstower_vanilla[player]
or world.logic[player] in ['owglitches', 'nologic']):
or world.logic[player] in ['owglitches', 'hybridglitches', 'nologic']):
continue
gt_count, total_count = calc_trash_locations(world, player)
scale_factor = .75 * (world.crystals_needed_for_gt[player] / 7)
@@ -734,24 +738,44 @@ def balance_multiworld_progression(world):
checked_locations = set()
unchecked_locations = set(world.get_locations())
total_locations_count = Counter(location.player for location in world.get_locations() if not location.locked and not location.forced_item)
reachable_locations_count = {}
for player in range(1, world.players + 1):
reachable_locations_count[player] = 0
sphere_num = 1
moved_item_count = 0
def get_sphere_locations(sphere_state, locations):
sphere_state.sweep_for_events(key_only=True, locations=locations)
return {loc for loc in locations if sphere_state.can_reach(loc) and sphere_state.not_flooding_a_key(sphere_state.world, loc)}
def item_percentage(player, num):
return num / total_locations_count[player]
while True:
sphere_locations = get_sphere_locations(state, unchecked_locations)
for location in sphere_locations:
unchecked_locations.remove(location)
reachable_locations_count[location.player] += 1
if not location.locked and not location.forced_item:
reachable_locations_count[location.player] += 1
logging.debug(f'Sphere {sphere_num}')
logging.debug(f'Reachable locations: {reachable_locations_count}')
debug_percentages = {
player: round(item_percentage(player, num), 2)
for player, num in reachable_locations_count.items()
}
logging.debug(f'Reachable percentages: {debug_percentages}\n')
sphere_num += 1
if checked_locations:
threshold = max(reachable_locations_count.values()) - 20
max_percentage = max(map(lambda p: item_percentage(p, reachable_locations_count[p]), reachable_locations_count))
threshold_percentages = {player: max_percentage * .8 for player in range(1, world.players + 1)}
logging.debug(f'Thresholds: {threshold_percentages}')
balancing_players = {player for player, reachables in reachable_locations_count.items() if reachables < threshold}
balancing_players = {player for player, reachables in reachable_locations_count.items()
if item_percentage(player, reachables) < threshold_percentages[player]}
if balancing_players:
balancing_state = state.copy()
balancing_unchecked_locations = unchecked_locations.copy()
@@ -769,7 +793,8 @@ def balance_multiworld_progression(world):
for location in balancing_sphere:
balancing_unchecked_locations.remove(location)
balancing_reachables[location.player] += 1
if world.has_beaten_game(balancing_state) or all(reachables >= threshold for reachables in balancing_reachables.values()):
if world.has_beaten_game(balancing_state) or all(item_percentage(player, reachables) >= threshold_percentages[player]
for player, reachables in balancing_reachables.items()):
break
elif not balancing_sphere:
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
@@ -796,7 +821,8 @@ def balance_multiworld_progression(world):
items_to_replace.append(testing)
else:
reduced_sphere = get_sphere_locations(reducing_state, locations_to_test)
if reachable_locations_count[player] + len(reduced_sphere) < threshold:
p = item_percentage(player, reachable_locations_count[player] + len(reduced_sphere))
if p < threshold_percentages[player]:
items_to_replace.append(testing)
replaced_items = False
@@ -821,6 +847,7 @@ def balance_multiworld_progression(world):
new_location.event, old_location.event = True, False
logging.debug(f"Progression balancing moved {new_location.item} to {new_location}, "
f"displacing {old_location.item} into {old_location}")
moved_item_count += 1
state.collect(new_location.item, True, new_location)
replaced_items = True
break
@@ -828,6 +855,7 @@ def balance_multiworld_progression(world):
logging.warning(f"Could not Progression Balance {old_location.item}")
if replaced_items:
logging.debug(f'Moved {moved_item_count} items so far\n')
unlocked = {fresh for player in balancing_players for fresh in unlocked_locations[player]}
for location in get_sphere_locations(state, unlocked):
unchecked_locations.remove(location)
@@ -842,7 +870,8 @@ def balance_multiworld_progression(world):
if world.has_beaten_game(state):
break
elif not sphere_locations:
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
logging.warning('Progression Balancing ran out of paths.')
break
def check_shop_swap(l, make_item_free=False):
@@ -1007,6 +1036,7 @@ def balance_money_progression(world):
logger.debug(f'Money balancing needed: Player {target_player} short {difference}')
else:
difference = 0
target_player = next(p for p in solvent)
while difference > 0:
swap_targets = [x for x in unchecked_locations if x not in sphere_locations and x.item.name.startswith('Rupees') and x.item.player == target_player]
if len(swap_targets) == 0:
+30 -27
View File
@@ -34,22 +34,34 @@ def check_python_version(fish):
import sys
version = sys.version_info
if version.major < 3 or version.minor < 7:
messagebox.showinfo("Door Shuffle " + ESVersion, fish.translate("cli","cli","old.python.version") % sys.version)
messagebox.showinfo("Overworld Shuffle %s (DR %s)" % (ORVersion, ESVersion), fish.translate("cli","cli","old.python.version") % sys.version)
# Save settings to file
def save_settings(gui, args, filename):
user_resources_path = os.path.join(".", "resources", "user")
settings_path = os.path.join(user_resources_path)
if not os.path.exists(settings_path):
os.makedirs(settings_path)
output_args = {}
settings = ["create_rom", "suppress_rom", "bps", "create_spoiler", "suppress_spoiler",
"calc_playthrough", "skip_playthrough", "print_custom_yaml",
"settingsonload", "rom", "enemizercli", "outputpath"]
if filename == "settings.json":
for s in settings:
output_args[s] = args[s]
for widget in gui.pages["adjust"].content.widgets:
output_args["adjust." + widget] = gui.pages["adjust"].content.widgets[widget].storageVar.get()
else:
for k, v in args.items():
if k not in settings and not k.startswith("adjust."):
output_args[k] = v
with open(os.path.join(settings_path, filename), "w+") as f:
f.write(json.dumps(output_args, indent=2))
os.chmod(os.path.join(settings_path, filename),0o755)
def guiMain(args=None):
# Save settings to file
def save_settings(args):
user_resources_path = os.path.join(".", "resources", "user")
settings_path = os.path.join(user_resources_path)
if not os.path.exists(settings_path):
os.makedirs(settings_path)
for widget in self.pages["adjust"].content.widgets:
args["adjust." + widget] = self.pages["adjust"].content.widgets[widget].storageVar.get()
with open(os.path.join(settings_path, "settings.json"), "w+") as f:
f.write(json.dumps(args, indent=2))
os.chmod(os.path.join(settings_path, "settings.json"),0o755)
# Save settings from GUI
def save_settings_from_gui(confirm):
gui_args = vars(create_guiargs(self))
@@ -57,23 +69,14 @@ def guiMain(args=None):
gui_args['sprite'] = 'random'
elif gui_args['sprite']:
gui_args['sprite'] = gui_args['sprite'].name
save_settings(gui_args)
save_settings(self, gui_args, "saved.json")
save_settings(self, gui_args, "settings.json")
if confirm:
messagebox.showinfo("Overworld Shuffle " + ORVersion, "Settings saved from GUI.")
# routine for exiting the app
def guiExit():
skip_exit = False
if self.settings['saveonexit'] == 'ask':
dosave = messagebox.askyesnocancel("Overworld Shuffle " + ORVersion, "Save settings before exit?")
if dosave:
save_settings_from_gui(True)
if dosave is None:
skip_exit = True
elif self.settings['saveonexit'] == 'always':
save_settings_from_gui(False)
if not skip_exit:
sys.exit(0)
sys.exit(0)
# make main window
# add program title & version number
@@ -172,8 +175,8 @@ def guiMain(args=None):
self.pages["bottom"].pages = {}
self.pages["bottom"].pages["content"] = bottom_frame(self, self, None)
## Save Settings Button
savesettingsButton = Button(self.pages["bottom"].pages["content"], text='Save Settings to File', command=lambda: save_settings_from_gui(True))
savesettingsButton.pack(side=RIGHT)
savesettingsButton = self.pages["bottom"].pages["content"].widgets["savesettings"].pieces["button"]
savesettingsButton.configure(command=lambda: save_settings_from_gui(True))
# set bottom frame to main window
self.pages["bottom"].pages["content"].pack(side=BOTTOM, fill=X, padx=5, pady=5)
+12 -1
View File
@@ -114,6 +114,16 @@ class InitialSram:
equip[0x37B] = 1
equip[0x36E] = 0x80
if startingstate.has('Return Old Man', player):
self._initial_sram_bytes[0x410] |= 0x01
if startingstate.has('Beat Agahnim 1', player):
self.pre_open_lumberjack()
if world.mode[player] == 'standard':
self.set_progress_indicator(0x80)
else:
self.set_progress_indicator(0x03)
for item in world.precollected_items:
if item.player != player:
continue
@@ -123,7 +133,8 @@ class InitialSram:
'Golden Sword', 'Tempered Sword', 'Master Sword', 'Fighter Sword', 'Progressive Sword',
'Mirror Shield', 'Red Shield', 'Blue Shield', 'Progressive Shield',
'Red Mail', 'Blue Mail', 'Progressive Armor',
'Magic Upgrade (1/4)', 'Magic Upgrade (1/2)']:
'Magic Upgrade (1/4)', 'Magic Upgrade (1/2)',
'Return Old Man', 'Beat Agahnim 1']:
continue
set_table = {'Book of Mudora': (0x34E, 1), 'Hammer': (0x34B, 1), 'Bug Catching Net': (0x34D, 1), 'Hookshot': (0x342, 1), 'Magic Mirror': (0x353, 2),
+28 -7
View File
@@ -227,6 +227,12 @@ def generate_itempool(world, player):
loc.locked = True
loc.forced_item = loc.item
if 'Return Old Man' in list(map(str, [i for i in world.precollected_items if i.player == player])):
old_man = world.get_location('Old Man', player)
world.push_item(old_man, ItemFactory('Nothing', player), False)
old_man.forced_item = old_man.item
old_man.skip = True
world.get_location('Ganon', player).event = True
world.get_location('Ganon', player).locked = True
world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False)
@@ -321,6 +327,11 @@ def generate_itempool(world, player):
for _ in range(0, amt):
pool.append('Rupees (20)')
if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave']:
# In HMG force swamp smalls in pots to allow getting out of swamp palace
placed_items['Swamp Palace - Trench 1 Pot Key'] = 'Small Key (Swamp Palace)'
placed_items['Swamp Palace - Pot Row Pot Key'] = 'Small Key (Swamp Palace)'
start_inventory = list(world.precollected_items)
for item in precollected_items:
world.push_precollected(ItemFactory(item, player))
@@ -335,6 +346,8 @@ def generate_itempool(world, player):
if not found_sword and world.swords[player] != 'swordless':
found_sword = True
possible_weapons.append(item)
if world.algorithm == 'vanilla_fill': # skip other possibilities
continue
if (item in ['Progressive Bow', 'Bow'] and not found_bow
and not world.bow_mode[player].startswith('retro')):
found_bow = True
@@ -428,9 +441,15 @@ def generate_itempool(world, player):
if tr_medallion == 'Random':
tr_medallion = None
if not mm_medallion:
mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
if world.algorithm == 'vanilla_fill':
mm_medallion = 'Ether'
else:
mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
if not tr_medallion:
tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
if world.algorithm == 'vanilla_fill':
tr_medallion = 'Quake'
else:
tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
world.required_medallions[player] = (mm_medallion, tr_medallion)
# shuffle bottle refills
@@ -552,7 +571,9 @@ def set_up_take_anys(world, player, skip_adjustments=False):
world.dynamic_regions.append(take_any)
target, room_id = random.choice([(0x58, 0x0112), (0x60, 0x010F), (0x46, 0x011F)])
reg = regions.pop()
entrance = world.get_region(reg, player).entrances[0]
entrance = next((ent for ent in world.get_region(reg, player).entrances if ent.parent_region.is_outdoors()), None)
if entrance is None:
raise Exception(f'No outside entrance found for {reg}')
connect_entrance(world, entrance, take_any, player)
entrance.target = target
take_any.shop = Shop(take_any, room_id, take_any_type, 0xE3, True, not world.shopsanity[player], 33 + num*2)
@@ -1040,7 +1061,7 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt
return random.choice([True, False]) if progressive == 'random' else progressive == 'on'
# provide boots to boots glitch dependent modes
if logic in ['owglitches', 'nologic']:
if logic in ['owglitches', 'hybridglitches', 'nologic']:
precollected_items.append('Pegasus Boots')
pool.remove('Pegasus Boots')
pool.extend(['Rupees (20)'])
@@ -1346,12 +1367,12 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer
start_inventory = [x for x in world.precollected_items if x.player == player]
if not start_inventory:
if world.logic[player] in ['owglitches', 'nologic']:
if world.logic[player] in ['owglitches', 'hybridglitches', 'nologic'] and all(x.name != 'Pegasus Boots' for x in start_inventory):
precollected_items.append('Pegasus Boots')
if 'Pegasus Boots' in pool:
pool.remove('Pegasus Boots')
pool.append('Rupees (20)')
if world.swords[player] == 'assured':
if world.swords[player] == 'assured' and all(' Sword' not in x.name for x in start_inventory):
precollected_items.append('Progressive Sword')
if 'Progressive Sword' in pool:
pool.remove('Progressive Sword')
@@ -1487,7 +1508,7 @@ def make_customizer_pool(world, player):
sphere_0 = world.customizer.get_start_inventory()
no_start_inventory = not sphere_0 or not sphere_0[player]
init_equip = [] if no_start_inventory else sphere_0[player]
if (world.logic[player] in ['owglitches', 'nologic']
if (world.logic[player] in ['owglitches', 'hybridglitches', 'nologic']
and (no_start_inventory or all(x != 'Pegasus Boots' for x in init_equip))):
precollected_items.append('Pegasus Boots')
if 'Pegasus Boots' in pool:
+16
View File
@@ -2106,6 +2106,22 @@ def validate_key_placement(key_layout, world, player):
if i.player == player and i.name == smallkey_name:
keys_outside += 1
if world.logic[player] == 'hybridglitches':
# Swamp keylogic
if smallkey_name.endswith('(Swamp Palace)'):
swamp_entrance = world.get_location('Swamp Palace - Entrance', player)
# Swamp small not vanilla
if swamp_entrance.item is None or (swamp_entrance.item.name != smallkey_name or swamp_entrance.item.player != player):
mire_keylayout = world.key_layout[player]['Misery Mire']
mire_smallkey_name = dungeon_keys[mire_keylayout.sector.name]
# Check if any mire keys are in swamp (excluding entrance), if none then add one to keys_outside
mire_keys_in_swamp = sum([1 if x.item.name == mire_smallkey_name else 0 for x in key_layout.item_locations if x.item is not None and x != swamp_entrance])
if mire_keys_in_swamp == 0:
keys_outside +=1
# Mire keylogic
if smallkey_name.endswith('(Tower of Hera)'):
# TODO: Make sure that mire medallion isn't in hera basement, or if it is, the small key is available downstairs
big_key_outside = True
for code, counter in key_layout.key_counters.items():
if len(counter.child_doors) == 0:
continue
+182 -93
View File
@@ -28,6 +28,7 @@ from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dunge
from Fill import dungeon_tracking
from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations, set_prize_drops
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops, fill_specific_items, create_farm_locations
from UnderworldGlitchRules import create_hybridmajor_connections, create_hybridmajor_connectors
from Utils import output_path, parse_player_names
from source.item.District import init_districts
@@ -35,7 +36,6 @@ from source.item.FillUtil import create_item_pool_config, massage_item_pool, dis
from source.overworld.EntranceShuffle2 import link_entrances_new
from source.tools.BPS import create_bps_from_data
from source.classes.CustomSettings import CustomSettings
from source.classes.SFX import output_song_data
version_number = '1.2.0.22'
version_branch = '-u'
@@ -57,32 +57,33 @@ def check_python_version():
def main(args, seed=None, fish=None):
check_python_version()
if args.print_template_yaml:
return export_yaml(args, fish)
if args.outputpath:
os.makedirs(args.outputpath, exist_ok=True)
output_path.cached_path = args.outputpath
start = time.perf_counter()
world = init_world(args, fish)
logger = logging.getLogger('')
if args.securerandom:
random.use_secure()
seeded = False
# initialize the world
if args.code:
for player, code in args.code.items():
if code:
Settings.adjust_args_from_code(code, player, args)
customized = None
if args.customizer:
customized = CustomSettings()
customized.load_yaml(args.customizer)
seed = customized.determine_seed(seed)
if world.customizer:
seed = world.customizer.determine_seed(seed)
seeded = True
customized.adjust_args(args)
world = World(args.multi, args.ow_shuffle, args.ow_crossed, args.ow_mixed, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords,
args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm,
args.accessibility, args.shuffleganon, args.custom, args.customitemarray, args.hints)
world.customizer = customized if customized else None
logger = logging.getLogger('')
world.customizer.adjust_args(args)
world = init_world(args, fish)
for i in zip(args.logic.values(), args.door_shuffle.values()):
if i[0] == 'hybridglitches' and i[1] != 'vanilla':
raise RuntimeError(BabelFish().translate("cli","cli","hybridglitches.door.shuffle"))
if seed is None:
random.seed(None)
world.seed = random.randint(0, 999999999)
@@ -94,53 +95,9 @@ def main(args, seed=None, fish=None):
if args.securerandom:
world.seed = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(9))
world.boots_hint = args.boots_hint.copy()
world.remote_items = args.remote_items.copy()
world.mapshuffle = args.mapshuffle.copy()
world.compassshuffle = args.compassshuffle.copy()
world.keyshuffle = args.keyshuffle.copy()
world.bigkeyshuffle = args.bigkeyshuffle.copy()
world.bombbag = args.bombbag.copy()
world.flute_mode = args.flute_mode.copy()
world.bow_mode = args.bow_mode.copy()
world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)}
world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)}
world.crystals_ganon_orig = args.crystals_ganon.copy()
world.crystals_gt_orig = args.crystals_gt.copy()
world.owTerrain = args.ow_terrain.copy()
world.owKeepSimilar = args.ow_keepsimilar.copy()
world.owWhirlpoolShuffle = args.ow_whirlpool.copy()
world.owFluteShuffle = args.ow_fluteshuffle.copy()
world.shuffle_bonk_drops = args.bonk_drops.copy()
world.open_pyramid = args.openpyramid.copy()
world.boss_shuffle = args.shufflebosses.copy()
world.enemy_shuffle = args.shuffleenemies.copy()
world.enemy_health = args.enemy_health.copy()
world.enemy_damage = args.enemy_damage.copy()
world.beemizer = args.beemizer.copy()
world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)}
world.door_type_mode = args.door_type_mode.copy()
world.trap_door_mode = args.trap_door_mode.copy()
world.key_logic_algorithm = args.key_logic_algorithm.copy()
world.decoupledoors = args.decoupledoors.copy()
world.door_self_loops = args.door_self_loops.copy()
world.experimental = args.experimental.copy()
world.dungeon_counters = args.dungeon_counters.copy()
world.fish = fish
world.shopsanity = args.shopsanity.copy()
world.dropshuffle = args.dropshuffle.copy()
world.pottery = args.pottery.copy()
world.potshuffle = args.shufflepots.copy()
world.mixed_travel = args.mixed_travel.copy()
world.standardize_palettes = args.standardize_palettes.copy()
world.shufflelinks = args.shufflelinks.copy()
world.shuffletavern = args.shuffletavern.copy()
world.pseudoboots = args.pseudoboots.copy()
world.overworld_map = args.overworld_map.copy()
world.take_any = args.take_any.copy()
world.restrict_boss_items = args.restrict_boss_items.copy()
world.collection_rate = args.collection_rate.copy()
world.colorizepots = args.colorizepots.copy()
world.treasure_hunt_count = {}
world.treasure_hunt_total = {}
@@ -184,8 +141,6 @@ def main(args, seed=None, fish=None):
for player, name in enumerate(team, 1):
world.player_names[player].append(name)
logger.info('')
world.settings = CustomSettings()
world.settings.create_from_world(world, args)
outfilebase = f'OR_{args.outputname if args.outputname else world.seed}'
@@ -196,13 +151,10 @@ def main(args, seed=None, fish=None):
if hasattr(world,"escape_assist") and player in world.escape_assist:
world.escape_assist[player].append('bombs') # enemized escape assumes infinite bombs available and will likely be unbeatable without it
if args.usestartinventory[player]:
for tok in filter(None, args.startinventory[player].split(',')):
name = tok.strip()
name = name if name != 'Ocarina' or world.flute_mode[player] != 'active' else 'Ocarina (Activated)'
item = ItemFactory(name, player)
if item:
world.push_precollected(item)
set_starting_inventory(world, args)
world.settings = CustomSettings()
world.settings.create_from_world(world, args)
if args.create_spoiler and not args.jsonout:
logger.info(world.fish.translate("cli", "cli", "create.meta"))
@@ -220,15 +172,8 @@ def main(args, seed=None, fish=None):
create_dungeons(world, player)
adjust_locations(world, player)
place_bosses(world, player)
if world.customizer and world.customizer.get_start_inventory():
for p, inv_list in world.customizer.get_start_inventory().items():
for inv_item in inv_list:
item = ItemFactory(inv_item.strip(), p)
if item:
world.push_precollected(item)
if args.print_custom_yaml:
world.settings.record_info(world)
if world.logic[player] in ('nologic', 'hybridglitches'):
create_hybridmajor_connections(world, player)
if any(world.potshuffle.values()):
logger.info(world.fish.translate("cli", "cli", "shuffling.pots"))
@@ -247,8 +192,6 @@ def main(args, seed=None, fish=None):
update_world_regions(world, player)
mark_light_dark_world_regions(world, player)
create_dynamic_exits(world, player)
if args.print_custom_yaml:
world.settings.record_overworld(world)
init_districts(world)
@@ -256,14 +199,14 @@ def main(args, seed=None, fish=None):
for player in range(1, world.players + 1):
link_entrances_new(world, player)
if world.logic[player] in ('nologic', 'hybridglitches'):
create_hybridmajor_connectors(world, player)
logger.info(world.fish.translate("cli", "cli", "shuffling.prep"))
for player in range(1, world.players + 1):
link_doors_prep(world, player)
if args.print_custom_yaml:
world.settings.record_entrances(world)
create_item_pool_config(world)
logger.info(world.fish.translate("cli", "cli", "shuffling.dungeons"))
@@ -271,8 +214,6 @@ def main(args, seed=None, fish=None):
for player in range(1, world.players + 1):
link_doors(world, player)
mark_light_dark_world_regions(world, player)
if args.print_custom_yaml:
world.settings.record_doors(world)
logger.info(world.fish.translate("cli", "cli", "generating.itempool"))
@@ -300,8 +241,6 @@ def main(args, seed=None, fish=None):
lock_shop_locations(world, player)
massage_item_pool(world)
if args.print_custom_yaml:
world.settings.record_item_pool(world)
logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes"))
fill_prizes(world)
@@ -351,6 +290,11 @@ def main(args, seed=None, fish=None):
ensure_good_pots(world, True)
if args.print_custom_yaml:
world.settings.record_info(world)
world.settings.record_overworld(world)
world.settings.record_entrances(world)
world.settings.record_doors(world)
world.settings.record_item_pool(world)
world.settings.record_item_placements(world)
world.settings.write_to_file(output_path(f'{outfilebase}_custom.yaml'))
@@ -405,8 +349,6 @@ def main(args, seed=None, fish=None):
if world.players > 1 or world.teams > 1:
outfilepname += f"_{world.player_names[player][team].replace(' ', '_')}" if world.player_names[player][team] != 'Player %d' % player else ''
outfilesuffix = f'_{Settings.make_code(world, player)}' if not args.outputname else ''
if args.shuffle_songinstruments:
output_song_data(rom, output_path('OR_SPCInstruments.txt'), outfilebase)
if args.bps:
patchfile = output_path(f'{outfilebase}{outfilepname}{outfilesuffix}.bps')
patch = create_bps_from_data(LocalRom(args.rom, patch=False).buffer, rom.buffer)
@@ -470,6 +412,124 @@ def main(args, seed=None, fish=None):
return world
def export_yaml(args, fish):
if args.outputpath:
os.makedirs(args.outputpath, exist_ok=True)
output_path.cached_path = args.outputpath
outfilebase = f'{args.outputname if args.outputname else "export"}'
logger = logging.getLogger('')
world = init_world(args, fish)
from OverworldShuffle import __version__ as ORVersion
logger.info(
world.fish.translate("cli","cli","app.title") + "\n",
ORVersion,
"(%s)" % outfilebase,
Settings.make_code(world, 1) if world.players == 1 else ''
)
for k,v in {"DR":__version__,"OR":ORVersion}.items():
logger.info((k + ' Version:').ljust(16) + '%s' % v)
set_starting_inventory(world, args)
world.settings = CustomSettings()
world.settings.create_from_world(world, args)
world.settings.record_item_pool(world, True)
world.settings.write_to_file(output_path(f'{outfilebase}.yaml'))
return world
def init_world(args, fish):
if args.code:
for player, code in args.code.items():
if code:
Settings.adjust_args_from_code(code, player, args)
customized = None
if args.customizer:
customized = CustomSettings()
customized.load_yaml(args.customizer)
customized.adjust_args(args, False)
world = World(args.multi, args.ow_shuffle, args.ow_crossed, args.ow_mixed, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords,
args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm,
args.accessibility, args.shuffleganon, args.custom, args.customitemarray, args.hints)
world.customizer = customized
world.boots_hint = args.boots_hint.copy()
world.remote_items = args.remote_items.copy()
world.mapshuffle = args.mapshuffle.copy()
world.compassshuffle = args.compassshuffle.copy()
world.keyshuffle = args.keyshuffle.copy()
world.bigkeyshuffle = args.bigkeyshuffle.copy()
world.bombbag = args.bombbag.copy()
world.flute_mode = args.flute_mode.copy()
world.bow_mode = args.bow_mode.copy()
world.crystals_ganon_orig = args.crystals_ganon.copy()
world.crystals_gt_orig = args.crystals_gt.copy()
world.owTerrain = args.ow_terrain.copy()
world.owKeepSimilar = args.ow_keepsimilar.copy()
world.owWhirlpoolShuffle = args.ow_whirlpool.copy()
world.owFluteShuffle = args.ow_fluteshuffle.copy()
world.shuffle_bonk_drops = args.bonk_drops.copy()
world.open_pyramid = args.openpyramid.copy()
world.boss_shuffle = args.shufflebosses.copy()
world.enemy_shuffle = args.shuffleenemies.copy()
world.enemy_health = args.enemy_health.copy()
world.enemy_damage = args.enemy_damage.copy()
world.beemizer = args.beemizer.copy()
world.intensity = {player: 'random' if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)}
world.door_type_mode = args.door_type_mode.copy()
world.trap_door_mode = args.trap_door_mode.copy()
world.key_logic_algorithm = args.key_logic_algorithm.copy()
world.decoupledoors = args.decoupledoors.copy()
world.door_self_loops = args.door_self_loops.copy()
world.experimental = args.experimental.copy()
world.dungeon_counters = args.dungeon_counters.copy()
world.fish = fish
world.shopsanity = args.shopsanity.copy()
world.dropshuffle = args.dropshuffle.copy()
world.pottery = args.pottery.copy()
world.potshuffle = args.shufflepots.copy()
world.mixed_travel = args.mixed_travel.copy()
world.standardize_palettes = args.standardize_palettes.copy()
world.shufflelinks = args.shufflelinks.copy()
world.shuffletavern = args.shuffletavern.copy()
world.pseudoboots = args.pseudoboots.copy()
world.overworld_map = args.overworld_map.copy()
world.take_any = args.take_any.copy()
world.restrict_boss_items = args.restrict_boss_items.copy()
world.collection_rate = args.collection_rate.copy()
world.colorizepots = args.colorizepots.copy()
world.aga_randomness = args.aga_randomness.copy()
return world
def set_starting_inventory(world, args):
for player in range(1, world.players + 1):
if args.usestartinventory[player]:
for tok in filter(None, args.startinventory[player].split(',')):
name = tok.strip()
name = name if name != 'Ocarina' or world.flute_mode[player] != 'active' else 'Ocarina (Activated)'
item = ItemFactory(name, player)
if item:
world.push_precollected(item)
if world.customizer and world.customizer.get_start_inventory():
for p, inv_list in world.customizer.get_start_inventory().items():
for inv_item in inv_list:
item = ItemFactory(inv_item.strip(), p)
if item:
world.push_precollected(item)
def copy_world(world):
# ToDo: Not good yet
ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
@@ -524,6 +584,10 @@ def copy_world(world):
ret.intensity = world.intensity.copy()
ret.decoupledoors = world.decoupledoors.copy()
ret.door_self_loops = world.door_self_loops.copy()
ret.door_type_mode = world.door_type_mode.copy()
ret.trap_door_mode = world.trap_door_mode.copy()
ret.key_logic_algorithm = world.key_logic_algorithm.copy()
ret.aga_randomness = world.aga_randomness.copy()
ret.experimental = world.experimental.copy()
ret.shopsanity = world.shopsanity.copy()
ret.dropshuffle = world.dropshuffle.copy()
@@ -540,8 +604,10 @@ def copy_world(world):
for player in range(1, world.players + 1):
create_regions(ret, player)
update_world_regions(ret, player)
if world.logic[player] in ('owglitches', 'nologic'):
if world.logic[player] in ('owglitches', 'hybridglitches', 'nologic'):
create_owg_connections(ret, player)
if world.logic[player] in ('nologic', 'hybridglitches'):
create_hybridmajor_connections(ret, player)
create_dynamic_exits(ret, player)
create_dungeon_regions(ret, player)
create_owedges(ret, player)
@@ -587,7 +653,12 @@ def copy_world(world):
for exit in region.exits:
if exit.connected_region:
dest_region = ret.get_region(exit.connected_region.name, region.player)
ret.get_entrance(exit.name, exit.player).connect(dest_region)
src_exit = ret.get_entrance(exit.name, exit.player)
if exit.name not in [e.name for e in dest_region.entrances if e.connected_region is not None]:
if exit.name in [e.name for e in dest_region.entrances]:
src_exit.connected_region = dest_region
else:
src_exit.connect(dest_region)
# fill locations
for location in world.get_locations():
@@ -644,6 +715,8 @@ def copy_world(world):
for player in range(1, world.players + 1):
categorize_world_regions(ret, player)
create_farm_locations(ret, player)
if world.logic[player] in ('nologic', 'hybridglitches'):
create_hybridmajor_connectors(ret, player)
set_rules(ret, player)
return ret
@@ -700,6 +773,12 @@ def copy_world_premature(world, player):
ret.enemy_damage = world.enemy_damage.copy()
ret.beemizer = world.beemizer.copy()
ret.intensity = world.intensity.copy()
ret.decoupledoors = world.decoupledoors.copy()
ret.door_self_loops = world.door_self_loops.copy()
ret.door_type_mode = world.door_type_mode.copy()
ret.trap_door_mode = world.trap_door_mode.copy()
ret.key_logic_algorithm = world.key_logic_algorithm.copy()
ret.aga_randomness = world.aga_randomness.copy()
ret.experimental = world.experimental.copy()
ret.shopsanity = world.shopsanity.copy()
ret.dropshuffle = world.dropshuffle.copy()
@@ -717,8 +796,10 @@ def copy_world_premature(world, player):
create_regions(ret, player)
update_world_regions(ret, player)
if world.logic[player] in ('owglitches', 'nologic'):
if world.logic[player] in ('owglitches', 'hybridglitches', 'nologic'):
create_owg_connections(ret, player)
if world.logic[player] in ('nologic', 'hybridglitches'):
create_hybridmajor_connections(ret, player)
create_dynamic_exits(ret, player)
create_dungeon_regions(ret, player)
create_owedges(ret, player)
@@ -749,7 +830,12 @@ def copy_world_premature(world, player):
for exit in region.exits:
if exit.connected_region:
dest_region = ret.get_region(exit.connected_region.name, region.player)
ret.get_entrance(exit.name, exit.player).connect(dest_region)
src_exit = ret.get_entrance(exit.name, exit.player)
if exit.name not in [e.name for e in dest_region.entrances if e.connected_region is not None]:
if exit.name in [e.name for e in dest_region.entrances]:
src_exit.connected_region = dest_region
else:
src_exit.connect(dest_region)
from OverworldShuffle import categorize_world_regions
categorize_world_regions(ret, player)
@@ -774,6 +860,9 @@ def copy_world_premature(world, player):
for portal in world.dungeon_portals[player]:
connect_portal(portal, ret, player)
if world.logic[player] in ('nologic', 'hybridglitches'):
create_hybridmajor_connectors(ret, player)
set_rules(ret, player)
return ret
+27 -24
View File
@@ -1558,23 +1558,39 @@ OWExitTypes = {
'Ice Lake Southeast Water Drop',
'Bomber Corner Waterfall Water Drop'
],
'OWTerrain': ['Lost Woods Bush (West)',
'Lost Woods Bush (East)',
'Old Man Drop Off',
'OpenTerrain': ['Old Man Drop Off',
'Spectacle Rock Approach',
'Spectacle Rock Leave',
'DM Hammer Bridge (West)',
'DM Hammer Bridge (East)',
'Floating Island Bridge (East)',
'Fairy Ascension Rocks (Inner)',
'DM Broken Bridge (West)',
'DM Broken Bridge (East)',
'Spiral Mimic Bridge (West)',
'Spiral Mimic Bridge (East)',
'Spiral Ledge Approach',
'Mimic Ledge Approach',
'Fairy Ascension Rocks (Outer)',
'Floating Island Bridge (West)',
'Graveyard Ladder (Bottom)',
'Graveyard Ladder (Top)',
'Hyrule Castle Main Gate (South)',
'Hyrule Castle Main Gate (North)',
'Stone Bridge (Northbound)',
'Stone Bridge (Southbound)',
'Checkerboard Ledge Approach',
'Checkerboard Ledge Leave',
'Cave 45 Approach',
'Cave 45 Leave',
'Middle Aged Man',
'Desert Pass Ladder (South)',
'Desert Pass Ladder (North)',
'GT Approach',
'GT Leave',
],
'OWTerrain': ['Lost Woods Bush (West)',
'Lost Woods Bush (East)',
'DM Hammer Bridge (West)',
'DM Hammer Bridge (East)',
'Fairy Ascension Rocks (Inner)',
'DM Broken Bridge (West)',
'DM Broken Bridge (East)',
'Fairy Ascension Rocks (Outer)',
'TR Pegs Ledge Entry',
'TR Pegs Ledge Leave',
'Mountain Pass Rock (Outer)',
@@ -1587,8 +1603,6 @@ OWExitTypes = {
'Lost Woods Pass Rock (North)',
'Lost Woods Pass Rock (South)',
'Kings Grave Rocks (Outer)',
'Graveyard Ladder (Bottom)',
'Graveyard Ladder (Top)',
'Kings Grave Rocks (Inner)',
'River Bend Water Drop',
'River Bend West Pier',
@@ -1602,12 +1616,10 @@ OWExitTypes = {
'Kakariko Yard Bush (South)',
'Kakariko Southwest Bush (South)',
'Kakariko Yard Bush (North)',
'Hyrule Castle Main Gate (South)',
'Hyrule Castle East Rock (Inner)',
'Hyrule Castle Southwest Bush (North)',
'Hyrule Castle Southwest Bush (South)',
'Hyrule Castle Courtyard Bush (South)',
'Hyrule Castle Main Gate (North)',
'Hyrule Castle Courtyard Bush (North)',
'Hyrule Castle East Rock (Outer)',
'Wooden Bridge Bush (South)',
@@ -1615,17 +1627,11 @@ OWExitTypes = {
'Blacksmith Ledge Peg (West)',
'Blacksmith Ledge Peg (East)',
'Maze Race Game',
'Stone Bridge (Northbound)',
'Stone Bridge (Southbound)',
'Desert Statue Move',
'Checkerboard Ledge Approach',
'Desert Ledge Rocks (Outer)',
'Desert Ledge Rocks (Inner)',
'Checkerboard Ledge Leave',
'Flute Boy Bush (South)',
'Cave 45 Approach',
'Flute Boy Bush (North)',
'Cave 45 Leave',
'C Whirlpool Rock (Bottom)',
'C Whirlpool Rock (Top)',
'C Whirlpool Pegs (Outer)',
@@ -1643,19 +1649,15 @@ OWExitTypes = {
'Lake Hylia East Pier',
'Lake Hylia Water D Approach',
'Lake Hylia Water D Leave',
'Desert Pass Ladder (South)',
'Ice Cave Pier',
'Desert Pass Rocks (North)',
'Desert Pass Rocks (South)',
'Desert Pass Ladder (North)',
'Middle Aged Man',
'Octoballoon Water Drop',
'Octoballoon Pier',
'Skull Woods Rock (East)',
'Skull Woods Rock (West)',
'Skull Woods Forgotten Bush (West)',
'Skull Woods Forgotten Bush (East)',
'GT Approach',
'GT Leave',
'East Dark Death Mountain Bushes',
'Bumper Cave Rock (Outer)',
'Bumper Cave Rock (Inner)',
@@ -1702,6 +1704,7 @@ OWExitTypes = {
'Ice Lake Northeast Pier',
'Ice Lake Northeast Pier Hop',
'Ice Lake Iceberg Water Entry',
'Shopping Mall Pier',
'Bomber Corner Water Drop',
'Bomber Corner Pier'
],
+89 -90
View File
@@ -5,102 +5,86 @@ Helper functions to deliver entrance/exit/region sets to OWG rules.
from BaseClasses import Entrance
from OWEdges import OWTileRegions
# Cave regions that superbunny can get through - but only with a sword.
sword_required_superbunny_mirror_regions = ["Spiral Cave (Top)"]
def get_sword_required_superbunny_mirror_regions():
"""
Cave regions that superbunny can get through - but only with a sword.
"""
yield 'Spiral Cave (Top)'
# Cave regions that superbunny can get through - but only with boots.
boots_required_superbunny_mirror_regions = ["Two Brothers House"]
def get_boots_required_superbunny_mirror_regions():
"""
Cave regions that superbunny can get through - but only with boots.
"""
yield 'Two Brothers House'
# Cave locations that superbunny can access - but only with boots.
boots_required_superbunny_mirror_locations = [
"Sahasrahla's Hut - Left",
"Sahasrahla's Hut - Middle",
"Sahasrahla's Hut - Right",
]
def get_boots_required_superbunny_mirror_locations():
"""
Cave locations that superbunny can access - but only with boots.
"""
yield 'Sahasrahla\'s Hut - Left'
yield 'Sahasrahla\'s Hut - Middle'
yield 'Sahasrahla\'s Hut - Right'
# Entrances that can't be superbunny-mirrored into.
invalid_mirror_bunny_entrances = [
"Hype Cave",
"Bonk Fairy (Dark)",
"Thieves Town",
"Hammer Peg Cave",
"Brewery",
"Hookshot Cave",
"Dark Lake Hylia Ledge Fairy",
"Dark Lake Hylia Ledge Spike Cave",
"Palace of Darkness",
"Misery Mire",
"Turtle Rock",
"Bonk Rock Cave",
"Bonk Fairy (Light)",
"50 Rupee Cave",
"20 Rupee Cave",
"Checkerboard Cave",
"Light Hype Fairy",
"Waterfall of Wishing",
"Light World Bomb Hut",
"Mini Moldorm Cave",
"Ice Rod Cave",
"Sanctuary Grave",
"Kings Grave",
"Sanctuary Grave",
"Hyrule Castle Secret Entrance Drop",
"Skull Woods Second Section Hole",
"Skull Woods First Section Hole (North)",
]
# Interior locations that can be accessed with superbunny state.
superbunny_accessible_locations = [
"Waterfall of Wishing - Left",
"Waterfall of Wishing - Right",
"King's Tomb",
"Floodgate",
"Floodgate Chest",
"Cave 45",
"Bonk Rock Cave",
"Brewery",
"C-Shaped House",
"Chest Game",
"Mire Shed - Left",
"Mire Shed - Right",
"Secret Passage",
"Ice Rod Cave",
"Pyramid Fairy - Left",
"Pyramid Fairy - Right",
"Superbunny Cave - Top",
"Superbunny Cave - Bottom",
"Blind's Hideout - Left",
"Blind's Hideout - Right",
"Blind's Hideout - Far Left",
"Blind's Hideout - Far Right",
"Kakariko Well - Left",
"Kakariko Well - Middle",
"Kakariko Well - Right",
"Kakariko Well - Bottom",
"Kakariko Tavern",
"Library",
"Spiral Cave",
] + boots_required_superbunny_mirror_locations
# TODO: Add pottery locations
def get_invalid_mirror_bunny_entrances():
"""
Entrances that can't be superbunny-mirrored into.
"""
yield 'Skull Woods Final Section'
yield 'Hype Cave'
yield 'Bonk Fairy (Dark)'
yield 'Thieves Town'
yield 'Hammer Peg Cave'
yield 'Brewery'
yield 'Hookshot Cave'
yield 'Dark Lake Hylia Ledge Fairy'
yield 'Dark Lake Hylia Ledge Spike Cave'
yield 'Palace of Darkness'
yield 'Misery Mire'
yield 'Turtle Rock'
yield 'Bonk Rock Cave'
yield 'Bonk Fairy (Light)'
yield '50 Rupee Cave'
yield '20 Rupee Cave'
yield 'Checkerboard Cave'
yield 'Light Hype Fairy'
yield 'Waterfall of Wishing'
yield 'Light World Bomb Hut'
yield 'Mini Moldorm Cave'
yield 'Ice Rod Cave'
yield 'Sanctuary Grave'
yield 'Kings Grave'
yield 'Sanctuary Grave'
yield 'Hyrule Castle Secret Entrance Drop'
yield 'Skull Woods Second Section Hole'
yield 'Skull Woods First Section Hole (North)'
def get_superbunny_accessible_locations():
"""
Interior locations that can be accessed with superbunny state.
"""
yield 'Waterfall of Wishing - Left'
yield 'Waterfall of Wishing - Right'
yield 'King\'s Tomb'
yield 'Floodgate'
yield 'Floodgate Chest'
yield 'Cave 45'
yield 'Bonk Rock Cave'
yield 'Brewery'
yield 'C-Shaped House'
yield 'Chest Game'
yield 'Mire Shed - Left'
yield 'Mire Shed - Right'
yield 'Secret Passage'
yield 'Ice Rod Cave'
yield 'Pyramid Fairy - Left'
yield 'Pyramid Fairy - Right'
yield 'Superbunny Cave - Top'
yield 'Superbunny Cave - Bottom'
yield 'Blind\'s Hideout - Left'
yield 'Blind\'s Hideout - Right'
yield 'Blind\'s Hideout - Far Left'
yield 'Blind\'s Hideout - Far Right'
yield 'Kakariko Well - Left'
yield 'Kakariko Well - Middle'
yield 'Kakariko Well - Right'
yield 'Kakariko Well - Bottom'
yield 'Kakariko Tavern'
yield 'Library'
yield 'Spiral Cave'
for location in get_boots_required_superbunny_mirror_locations():
yield location
def get_non_mandatory_exits(world, player):
"""
Entrances that can be reached with full equipment using overworld glitches and don't need to be an exit.
@@ -295,6 +279,7 @@ def overworld_glitches_rules(world, player):
#set_owg_rules(player, world, get_glitched_speed_drops_dw(world, player), lambda state: state.can_get_glitched_speed_dw(player))
# Mirror clip spots.
# TODO: Should this also require can_boots_clip
set_owg_rules(player, world, get_mirror_clip_spots(world, player), lambda state: state.has_Mirror(player))
# Mirror offset spots.
@@ -319,6 +304,18 @@ def overworld_glitches_rules(world, player):
add_additional_rule(world.get_entrance('Tree Line Water Clip', player), lambda state: state.has('Flippers', player))
add_additional_rule(world.get_entrance('Dark Tree Line Water Clip', player), lambda state: state.has('Flippers', player))
# Bunny pocket
if not world.is_tile_swapped(0x00, player):
add_alternate_rule(world.get_entrance("Skull Woods Final Section", player), lambda state: state.can_bunny_pocket(player) and state.has("Fire Rod", player))
if world.is_tile_swapped(0x05, player):
add_alternate_rule(world.get_entrance("DM Hammer Bridge (West)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
add_alternate_rule(world.get_entrance("DM Hammer Bridge (East)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
if not world.is_tile_swapped(0x18, player):
add_alternate_rule(world.get_entrance("Bush Yard Pegs (Inner)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
add_alternate_rule(world.get_entrance("Bush Yard Pegs (Outer)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
if world.is_tile_swapped(0x22, player):
add_alternate_rule(world.get_entrance("Blacksmith Ledge Peg (West)", player), lambda state: state.can_bunny_pocket(player) and state.has("Hammer", player))
def add_alternate_rule(entrance, rule):
old_rule = entrance.access_rule
@@ -335,7 +332,7 @@ def create_no_logic_connections(player, world, connections):
parent = world.get_region(parent_region, player)
target = world.get_region(target_region, player)
connection = Entrance(player, entrance, parent)
connection.spot_type = 'Ledge'
connection.spot_type = 'OWG'
parent.exits.append(connection)
connection.connect(target)
@@ -387,6 +384,8 @@ boots_clips_local = [ # (name, from_region, to_region)
('Maze Race Item Get Ledge Clip', 'Maze Race Area', 'Maze Race Prize'),
#('Hobo Water Clip', 'Stone Bridge South Area', 'Stone Bridge Water'), # TODO: Doesn't work with OW Free Terrain
('Tree Line Water Clip', 'Tree Line Area', 'Tree Line Water'), #requires flippers
('Dark Tree Line Water Clip', 'Dark Tree Line Area', 'Dark Tree Line Water'), #requires flippers
+3 -3
View File
@@ -8,7 +8,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType
from OverworldGlitchRules import create_owg_connections
from Utils import bidict
version_number = '0.3.3.2'
version_number = '0.3.4.0'
# branch indicator is intentionally different across branches
version_branch = ''
@@ -200,7 +200,7 @@ def link_overworld(world, player):
categorize_world_regions(world, player)
if world.logic[player] in ('owglitches', 'nologic'):
if world.logic[player] in ('owglitches', 'hybridglitches', 'nologic'):
create_owg_connections(world, player)
# crossed shuffle
@@ -1486,7 +1486,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
elif exit.connected_region.name not in explored_regions \
and (exit.connected_region.type == region.type
or exit.name in OWExitTypes['OWEdge'] or (cross_world and exit.name in (OWExitTypes['Portal'] + OWExitTypes['Mirror']))) \
and (not region_rules or exit.access_rule(blank_state)) and (not ignore_ledges or exit.name not in OWExitTypes['Ledge']):
and (not region_rules or exit.access_rule(blank_state)) and (not ignore_ledges or exit.name not in OWExitTypes['Ledge', 'OWG']):
explore_region(exit.connected_region.name, exit.connected_region)
if build_copy_world:
+15 -1
View File
@@ -109,7 +109,21 @@ These are now independent of retro mode and have three options: None, Random, an
# Bug Fixes and Notes
* 1.2.0.22u
* 1.4.0.1v
* Key logic: Vanilla key logic fixes. Statically set some HC logic and PoD front door
* 1.4.0.0v
* Generation: fix for bunny walk logic taking up too much memory
* Key Logic: Partial is now the new default
* 1.3.0.9v
* Ganonhunt: playthrough no longer collects crystals
* Vanilla Fill: Uncle weapon is always a sword, medallions for Mire/TR will be vanilla
* Customizer: support shufflebosses/shuffleenemies as well as boss_shuffle/enemy_shuffle
* 1.3.0.8v
* No Logic Standard ER: Rain doors aren't blocked if no logic is enabled.
* MW Progression Balancing: Change to be percentage based instead of raw count. (80% threshold)
* Take anys: Good Bee cave chosen as take any should no longer prevent generation
* Money balancing: Fixed generation issue
1.2.0.22u
* Flute can't be activated in rain state (except glitched modes) (Thanks codemann!)
* ER: Minor fix for Link's House on DM in Insanity (escape cave should not be re-used)
* Logic issues:
+26 -26
View File
@@ -1287,32 +1287,32 @@ bonk_prize_table = {
'Forgotten Forest Southwest Tree': (0x0e, 0x10, False, '', 'Forgotten Forest Area', 'in a tree'),
'Forgotten Forest Central Tree': (0x0f, 0x08, False, '', 'Forgotten Forest Area', 'in a tree'),
#'Forgotten Forest Southeast Tree': (0x10, 0x04, False, '', 'Forgotten Forest Area', 'in a tree'),
'Hyrule Castle Tree': (0x11, 0x10, False, '', 'Hyrule Castle Courtyard', 'in a tree'),
'Wooden Bridge Tree': (0x12, 0x10, False, '', 'Wooden Bridge Area', 'in a tree'),
'Eastern Palace Tree': (0x13, 0x10, True, '', 'Eastern Palace Area', 'in a tree'),
'Flute Boy South Tree': (0x14, 0x10, True, '', 'Flute Boy Area', 'in a tree'),
'Flute Boy East Tree': (0x15, 0x08, True, '', 'Flute Boy Area', 'in a tree'),
'Central Bonk Rocks Tree': (0x16, 0x10, False, '', 'Central Bonk Rocks Area', 'in a tree'),
'Tree Line Tree 2': (0x17, 0x10, True, '', 'Tree Line Area', 'in a tree'),
'Tree Line Tree 4': (0x18, 0x08, True, '', 'Tree Line Area', 'in a tree'),
'Flute Boy Approach South Tree': (0x19, 0x10, False, '', 'Flute Boy Approach Area', 'in a tree'),
'Flute Boy Approach North Tree': (0x1a, 0x08, False, '', 'Flute Boy Approach Area', 'in a tree'),
'Dark Lumberjack Tree': (0x1b, 0x10, False, '', 'Dark Lumberjack Area', 'in a tree'),
'Dark Fortune Bonk Rocks (Drop 1)': (0x1c, 0x10, False, '', 'Dark Fortune Area', 'encased in stone'),
'Dark Fortune Bonk Rocks (Drop 2)': (0x1d, 0x08, False, '', 'Dark Fortune Area', 'encased in stone'),
'Dark Graveyard West Bonk Rocks': (0x1e, 0x10, False, '', 'Dark Graveyard Area', 'encased in stone'),
'Dark Graveyard North Bonk Rocks': (0x1f, 0x08, False, '', 'Dark Graveyard North', 'encased in stone'),
'Dark Graveyard Tomb Bonk Rocks': (0x20, 0x04, False, '', 'Dark Graveyard North', 'encased in stone'),
'Qirn Jump West Tree': (0x21, 0x10, False, '', 'Qirn Jump Area', 'in a tree'),
'Qirn Jump East Tree': (0x22, 0x08, False, '', 'Qirn Jump East Bank', 'in a tree'),
'Dark Witch Tree': (0x23, 0x10, False, '', 'Dark Witch Area', 'in a tree'),
'Pyramid Tree': (0x24, 0x10, False, '', 'Pyramid Area', 'in a tree'),
'Palace of Darkness Tree': (0x25, 0x10, False, '', 'Palace of Darkness Area', 'in a tree'),
'Dark Tree Line Tree 2': (0x26, 0x10, False, '', 'Dark Tree Line Area', 'in a tree'),
'Dark Tree Line Tree 3': (0x27, 0x08, False, '', 'Dark Tree Line Area', 'in a tree'),
'Dark Tree Line Tree 4': (0x28, 0x04, False, '', 'Dark Tree Line Area', 'in a tree'),
'Hype Cave Statue': (0x29, 0x10, False, '', 'Hype Cave Area', 'encased in stone'),
'Cold Fairy Statue': (0x2a, 0x02, False, '', 'Good Bee Cave', 'encased in stone')
'Hyrule Castle Tree': (0x10, 0x10, False, '', 'Hyrule Castle Courtyard', 'in a tree'),
'Wooden Bridge Tree': (0x11, 0x10, False, '', 'Wooden Bridge Area', 'in a tree'),
'Eastern Palace Tree': (0x12, 0x10, True, '', 'Eastern Palace Area', 'in a tree'),
'Flute Boy South Tree': (0x13, 0x10, True, '', 'Flute Boy Area', 'in a tree'),
'Flute Boy East Tree': (0x14, 0x08, True, '', 'Flute Boy Area', 'in a tree'),
'Central Bonk Rocks Tree': (0x15, 0x10, False, '', 'Central Bonk Rocks Area', 'in a tree'),
'Tree Line Tree 2': (0x16, 0x10, True, '', 'Tree Line Area', 'in a tree'),
'Tree Line Tree 4': (0x17, 0x08, True, '', 'Tree Line Area', 'in a tree'),
'Flute Boy Approach South Tree': (0x18, 0x10, False, '', 'Flute Boy Approach Area', 'in a tree'),
'Flute Boy Approach North Tree': (0x19, 0x08, False, '', 'Flute Boy Approach Area', 'in a tree'),
'Dark Lumberjack Tree': (0x1a, 0x10, False, '', 'Dark Lumberjack Area', 'in a tree'),
'Dark Fortune Bonk Rocks (Drop 1)': (0x1b, 0x10, False, '', 'Dark Fortune Area', 'encased in stone'),
'Dark Fortune Bonk Rocks (Drop 2)': (0x1c, 0x08, False, '', 'Dark Fortune Area', 'encased in stone'),
'Dark Graveyard West Bonk Rocks': (0x1d, 0x10, False, '', 'Dark Graveyard Area', 'encased in stone'),
'Dark Graveyard North Bonk Rocks': (0x1e, 0x08, False, '', 'Dark Graveyard North', 'encased in stone'),
'Dark Graveyard Tomb Bonk Rocks': (0x1f, 0x04, False, '', 'Dark Graveyard North', 'encased in stone'),
'Qirn Jump West Tree': (0x20, 0x10, False, '', 'Qirn Jump Area', 'in a tree'),
'Qirn Jump East Tree': (0x21, 0x08, False, '', 'Qirn Jump East Bank', 'in a tree'),
'Dark Witch Tree': (0x22, 0x10, False, '', 'Dark Witch Area', 'in a tree'),
'Pyramid Tree': (0x23, 0x10, False, '', 'Pyramid Area', 'in a tree'),
'Palace of Darkness Tree': (0x24, 0x10, False, '', 'Palace of Darkness Area', 'in a tree'),
'Dark Tree Line Tree 2': (0x25, 0x10, False, '', 'Dark Tree Line Area', 'in a tree'),
'Dark Tree Line Tree 3': (0x26, 0x08, False, '', 'Dark Tree Line Area', 'in a tree'),
'Dark Tree Line Tree 4': (0x27, 0x04, False, '', 'Dark Tree Line Area', 'in a tree'),
'Hype Cave Statue': (0x28, 0x10, False, '', 'Hype Cave Area', 'encased in stone'),
'Cold Fairy Statue': (0x29, 0x02, False, '', 'Good Bee Cave', 'encased in stone')
}
bonk_table_by_location_id = {0x2ABB00+(data[0]*6)+3: name for name, data in bonk_prize_table.items()}
+11 -10
View File
@@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'fe9e7870071daa40829c1072829bf30b'
RANDOMIZERBASEHASH = '3f08ebba5a2c79b373dbd0c9151ade9b'
class JsonRom(object):
@@ -802,10 +802,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
# setting spriteID to D8, a placeholder sprite we use to inform ROM to spawn a dynamic item
#for address in bonk_addresses:
for address in [b for b in bonk_addresses if b != 0x4D0AE]: # temp fix for screen 1A murahdahla sprite replacement
rom.write_byte(address, 0xD8)
rom.write_byte(address, 0xD9)
# temporary fix for screen 1A
rom.write_byte(snes_to_pc(0x09AE32), 0xD8)
rom.write_byte(snes_to_pc(0x09AE35), 0xD8)
rom.write_byte(snes_to_pc(0x09AE32), 0xD9)
rom.write_byte(snes_to_pc(0x09AE35), 0xD9)
rom.write_byte(snes_to_pc(0x06918E), 0x80) # skip good bee bottle check
@@ -1365,9 +1365,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x180211, gametype) # Game type
warningflags = 0x00 # none
if world.logic[player] in ['owglitches', 'nologic']:
if world.logic[player] in ['owglitches', 'hybridglitches', 'nologic']:
warningflags |= 0x20
if world.logic[player] in ['minorglitches', 'owglitches', 'nologic']:
if world.logic[player] in ['minorglitches', 'owglitches', 'hybridglitches', 'nologic']:
warningflags |= 0x40
rom.write_byte(0x180212, warningflags) # Warning flags
@@ -1391,7 +1391,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x18008F, 0x01 if world.is_atgt_swapped(player) else 0x00) # AT/GT swapped
rom.write_byte(0xF5D73, 0xF0) # bees are catchable
rom.write_byte(0xF5F10, 0xF0) # bees are catchable
rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness
rom.write_byte(0x180086, 0x00 if world.aga_randomness[player] else 0x01) # set blue ball and ganon warp randomness
rom.write_byte(0x1800A0, 0x01) # return to light world on s+q without mirror
rom.write_byte(0x1800A1, 0x01) # enable overworld screen transition draining for water level inside swamp
rom.write_byte(0x180174, 0x01 if world.fix_fake_world[player] else 0x00)
@@ -1434,10 +1434,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x18005F, world.crystals_needed_for_ganon[player])
# block HC upstairs doors in rain state in standard mode
prevent_rain = world.mode[player] == "standard" and world.shuffle[player] != 'vanilla'
prevent_rain = world.mode[player] == 'standard' and world.shuffle[player] != 'vanilla' and world.logic[player] != 'nologic'
rom.write_byte(0x18008A, 0x01 if prevent_rain else 0x00)
# block sanc door in rain state and the dungeon is not vanilla
rom.write_byte(0x13f0fa, 0x01 if world.mode[player] == "standard" and world.doorShuffle[player] != 'vanilla' else 0x00)
block_sanc = world.mode[player] == 'standard' and world.doorShuffle[player] != 'vanilla' and world.logic[player] != 'nologic'
rom.write_byte(0x13f0fa, 0x01 if block_sanc else 0x00)
if prevent_rain:
portals = [world.get_portal('Hyrule Castle East', player), world.get_portal('Hyrule Castle West', player)]
@@ -1598,7 +1599,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills
rom.write_byte(0x1800A4, 0x01 if world.logic[player] != 'nologic' else 0x00) # enable POD EG fix
rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill
rom.write_byte(0x180358, 0x01 if (world.logic[player] in ['owglitches', 'nologic']) else 0x00)
rom.write_byte(0x180358, 0x01 if (world.logic[player] in ['owglitches', 'hybridglitches', 'nologic']) else 0x00)
# remove shield from uncle
rom.write_bytes(0x6D253, [0x00, 0x00, 0xf6, 0xff, 0x00, 0x0E])
+76 -24
View File
@@ -9,6 +9,7 @@ from Dungeons import dungeon_table
from RoomData import DoorKind
from OWEdges import OWExitTypes
from OverworldGlitchRules import overworld_glitches_rules
from UnderworldGlitchRules import underworld_glitches_rules
def set_rules(world, player):
@@ -32,7 +33,7 @@ def set_rules(world, player):
logging.getLogger('').info('Minor Glitches may be buggy still. No guarantee for proper logic checks.')
no_glitches_rules(world, player)
fake_flipper_rules(world, player)
elif world.logic[player] == 'owglitches':
elif world.logic[player] in ['owglitches', 'hybridglitches']:
logging.getLogger('').info('There is a chance OWG has bugged edge case rulesets, especially in inverted. Definitely file a report on GitHub if you see anything strange.')
# Initially setting no_glitches_rules to set the baseline rules for some
# entrances. The overworld_glitches_rules set is primarily additive.
@@ -84,6 +85,9 @@ def set_rules(world, player):
if not world.is_copied_world:
set_bunny_rules(world, player, world.mode[player] == 'inverted')
# These rules go here because they overwrite/add to some of the above rules
if world.logic[player] == 'hybridglitches':
underworld_glitches_rules(world, player)
def mirrorless_path_to_location(world, startName, targetName, player):
# If Agahnim is defeated then the courtyard needs to be accessible without using the mirror for the mirror offset glitch.
@@ -604,10 +608,10 @@ def global_rules(world, player):
set_rule(location, lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('TR Final Abyss Balcony Path', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('TR Final Abyss Ledge Path', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Left', player), lambda state: state.has('Cane of Byrna', player) or state.has('Cape', player) or state.has('Mirror Shield', player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Right', player), lambda state: state.has('Cane of Byrna', player) or state.has('Cape', player) or state.has('Mirror Shield', player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Left', player), lambda state: state.has('Cane of Byrna', player) or state.has('Cape', player) or state.has('Mirror Shield', player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Right', player), lambda state: state.has('Cane of Byrna', player) or state.has('Cape', player) or state.has('Mirror Shield', player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Left', player), lambda state: state.can_avoid_lasers(player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Bottom Right', player), lambda state: state.can_avoid_lasers(player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Left', player), lambda state: state.can_avoid_lasers(player))
set_rule(world.get_location('Turtle Rock - Eye Bridge - Top Right', player), lambda state: state.can_avoid_lasers(player))
set_defeat_dungeon_boss_rule(world.get_location('Turtle Rock - Boss', player))
set_defeat_dungeon_boss_rule(world.get_location('Turtle Rock - Prize', player))
@@ -845,6 +849,9 @@ def global_rules(world, player):
set_rule(world.get_entrance('GT Crystal Circles to Ranged Crystal', player), lambda state: state.can_hit_crystal_through_barrier(player) or state.has_blunt_weapon(player) or state.has('Cane of Byrna', player)) # or state.has_beam_sword(player)
add_key_logic_rules(world, player)
if world.logic[player] == 'hybridglitches':
add_hmg_key_logic_rules(world, player)
# End of door rando rules.
if world.restrict_boss_items[player] != 'none':
@@ -864,8 +871,11 @@ def global_rules(world, player):
add_mc_rule('Agahnim 1')
add_mc_rule('Agahnim 2')
set_rule(world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player)
set_rule(world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player)
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times
if world.goal[player] != 'ganonhunt':
add_rule(world.get_location('Ganon', player), lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player))
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
@@ -1541,6 +1551,7 @@ def standard_rules(world, player):
world.get_entrance('Uncle S&Q', player).hide_path = True
set_rule(world.get_entrance('Links House S&Q', player), lambda state: state.has('Zelda Delivered', player))
set_rule(world.get_entrance('Sanctuary S&Q', player), lambda state: state.has('Zelda Delivered', player))
add_rule(world.get_entrance('Old Man S&Q', player), lambda state: state.has('Zelda Delivered', player))
# these are because of rails
if world.shuffle[player] != 'vanilla':
# where ever these happen to be
@@ -1640,6 +1651,8 @@ def find_rules_for_zelda_delivery(world, player):
def set_bunny_rules(world, player, inverted):
# regions for the exits of multi-entrace caves/drops that bunny cannot pass
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing.
all_single_exit_dungeons = ['Eastern Palace', 'Tower of Hera', 'Castle Tower', 'Palace of Darkness', 'Swamp Palace', 'Thieves Town', 'Ice Palace', 'Misery Mire', 'Ganons Tower']
hmg_single_exit_dungeons = [d for d in all_single_exit_dungeons if d not in ['Tower of Hera', 'Misery Mire', 'Thieves Town']]
bunny_impassable_caves = ['Bumper Cave (top)', 'Bumper Cave (bottom)', 'Two Brothers House',
'Hookshot Cave (Middle)', 'Pyramid', 'Spiral Cave (Top)', 'Fairy Ascension Cave (Drop)']
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree',
@@ -1664,6 +1677,9 @@ def set_bunny_rules(world, player, inverted):
'Take - Any # 3 Item 1', 'Take - Any # 3 Item 2',
'Take - Any # 4 Item 1', 'Take - Any # 4 Item 2',
]
bunny_pocket_entrances = ['Skull Woods Final Section', 'Bush Yard Pegs (Inner)', 'Bush Yard Pegs (Outer)',
'DM Hammer Bridge (West)', 'DM Hammer Bridge (East)', 'Blacksmith Ledge Peg (West)'
]
def path_to_access_rule(path, entrance):
return lambda state: state.can_reach(entrance) and all(rule_func(state) for rule_func in path)
@@ -1684,12 +1700,31 @@ def set_bunny_rules(world, player, inverted):
else:
return region.is_light_world
# Is it possible to do bunny pocket here
def can_bunny_pocket_to(world, entrance_name, player):
def can_activate_bunny_pocket(region):
explored_regions.append(region.name)
for ent in region.entrances:
if (is_link(ent.parent_region) or
(ent.parent_region.type == RegionType.Dungeon and ent.parent_region.name in bunny_revivable_entrances)):
return True
for ent in region.entrances:
if ent.spot_type in ['OWEdge', 'Ledge', 'OpenTerrain'] and ent.parent_region.name not in explored_regions:
if can_activate_bunny_pocket(ent.parent_region):
return True
return False
entrance = world.get_entrance(entrance_name, player)
explored_regions = []
return can_activate_bunny_pocket(entrance.parent_region)
def get_rule_to_add(region, location=None, connecting_entrance=None):
# In OWG, a location can potentially be superbunny-mirror accessible or
# bunny revival accessible.
if world.logic[player] == 'owglitches':
if world.logic[player] in ['owglitches', 'hybridglitches']:
if region.type != RegionType.Dungeon \
and (location is None or location.name not in OverworldGlitchRules.get_superbunny_accessible_locations()) \
and (location is None or location.name not in OverworldGlitchRules.superbunny_accessible_locations) \
and not is_link(region):
return lambda state: state.has_Pearl(player)
else:
@@ -1707,25 +1742,30 @@ def set_bunny_rules(world, player, inverted):
# for each such entrance a new option is added that consist of:
# a) being able to reach it, and
# b) being able to access all entrances from there to `region`
seen = {region}
queue = deque([(region, [])])
queue = deque([(region, [], {region})])
seen_sets = set([frozenset({region})])
while queue:
(current, path) = queue.popleft()
(current, path, seen) = queue.popleft()
for entrance in current.entrances:
new_region = entrance.parent_region
if new_region.type in (RegionType.Cave, RegionType.Dungeon) and new_region in seen:
new_seen = seen.union({new_region})
if new_region.type in (RegionType.Cave, RegionType.Dungeon) and new_seen in seen_sets:
continue
new_path = path + [entrance.access_rule]
seen.add(new_region)
seen_sets.add(frozenset(new_seen))
if not is_link(new_region):
if world.logic[player] == 'owglitches':
if world.logic[player] in ['owglitches', 'hybridglitches']:
# Is this a bunny pocketable entrance?
if region.type == RegionType.Dungeon and new_region.type != RegionType.Dungeon:
if entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances():
if entrance.name in OverworldGlitchRules.invalid_mirror_bunny_entrances:
continue
if entrance.name in bunny_pocket_entrances and not can_bunny_pocket_to(world, entrance.name, player):
continue
if entrance.name in drop_dungeon_entrances:
lobby = entrance.connected_region
else:
lobby = next(exit.connected_region for exit in current.exits if exit.connected_region.type == RegionType.Dungeon)
portal_regions = [world.get_region(reg, player) for reg in region.dungeon.regions if reg.endswith('Portal')]
lobby = next(reg.connected_region for portal_reg in portal_regions for reg in portal_reg.exits if reg.name.startswith('Enter '))
if lobby.name in bunny_revivable_entrances:
possible_options.append(path_to_access_rule(new_path, entrance))
elif lobby.name in superbunny_revivable_entrances:
@@ -1734,26 +1774,29 @@ def set_bunny_rules(world, player, inverted):
possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player) and state.has_sword(player)], entrance))
continue
elif region.type == RegionType.Cave and new_region.type != RegionType.Cave:
if entrance.name in OverworldGlitchRules.get_invalid_mirror_bunny_entrances():
if entrance.name in OverworldGlitchRules.invalid_mirror_bunny_entrances:
continue
if region.name in OverworldGlitchRules.get_sword_required_superbunny_mirror_regions():
if entrance.name in bunny_pocket_entrances and not can_bunny_pocket_to(world, entrance.name, player):
continue
if region.name in OverworldGlitchRules.sword_required_superbunny_mirror_regions:
possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player) and state.has_sword(player)], entrance))
elif region.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_regions():
elif region.name in OverworldGlitchRules.boots_required_superbunny_mirror_regions:
possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player) and state.has_Boots(player)], entrance))
elif location and location.name in OverworldGlitchRules.get_superbunny_accessible_locations():
if location.name in OverworldGlitchRules.get_boots_required_superbunny_mirror_locations():
elif location and location.name in OverworldGlitchRules.superbunny_accessible_locations:
if location.name in OverworldGlitchRules.boots_required_superbunny_mirror_locations:
possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player) and state.has_Boots(player)], entrance))
elif region.name == 'Kakariko Well (top)':
possible_options.append(path_to_access_rule(new_path, entrance))
else:
possible_options.append(path_to_access_rule(new_path + [lambda state: state.has_Mirror(player)], entrance))
continue
elif region.name == 'Superbunny Cave (Top)' and new_region.name == 'Superbunny Cave (Bottom)' and location and location.name in OverworldGlitchRules.get_superbunny_accessible_locations():
elif region.name == 'Superbunny Cave (Top)' and new_region.name == 'Superbunny Cave (Bottom)' and location and location.name in OverworldGlitchRules.superbunny_accessible_locations:
possible_options.append(path_to_access_rule(new_path, entrance))
else:
continue
if is_bunny(new_region):
queue.append((new_region, new_path))
# todo: if not owg or hmg and entrance is in bunny_impassible_doors, then skip this nonsense?
queue.append((new_region, new_path, new_seen))
else:
# we have reached pure light world, so we have a new possible option
possible_options.append(path_to_access_rule(new_path, entrance))
@@ -1761,7 +1804,6 @@ def set_bunny_rules(world, player, inverted):
# Add requirements for bunny-impassible caves if they occur in the light world
for region in [world.get_region(name, player) for name in bunny_impassable_caves]:
if not is_bunny(region):
continue
rule = get_rule_to_add(region)
@@ -1796,6 +1838,11 @@ def set_bunny_rules(world, player, inverted):
continue
add_rule(location, get_rule_to_add(region, location))
for ent_name in bunny_pocket_entrances:
bunny_exit = world.get_entrance(ent_name, player)
if bunny_exit.connected_region and is_bunny(bunny_exit.parent_region) and not can_bunny_pocket_to(world, ent_name, player):
add_rule(bunny_exit, lambda state: state.has_Pearl(player))
drop_dungeon_entrances = {
"Sewer Drop",
@@ -1923,6 +1970,11 @@ bunny_impassible_if_trapped = {
'GT Speed Torch WN', 'Ice Lobby SE'
}
def add_hmg_key_logic_rules(world, player):
for toh_loc in world.key_logic[player]['Tower of Hera'].bk_restricted:
set_always_allow(world.get_location(toh_loc.name, player), allow_big_key_in_big_chest('Big Key (Tower of Hera)', player))
set_always_allow(world.get_location('Swamp Palace - Entrance', player), allow_big_key_in_big_chest('Big Key (Swamp Palace)', player))
def add_key_logic_rules(world, player):
key_logic = world.key_logic[player]
+278
View File
@@ -0,0 +1,278 @@
from BaseClasses import Entrance
import Rules
from OverworldGlitchRules import create_no_logic_connections
kikiskip_spots = [("Kiki Skip", "Spectacle Rock Cave (Bottom)", "Palace of Darkness Portal")]
mireheraswamp_spots = [
("Mire to Hera Clip", "Mire Torches Top", "Hera Portal"),
("Hera to Swamp Clip", "Mire Torches Top", "Swamp Portal"),
]
icepalace_spots = [("Ice Lobby Clip", "Ice Portal", "Ice Bomb Drop")]
thievesdesert_spots = [
("Thieves to Desert Clip", "Thieves Attic", "Desert West Portal"),
("Thieves to Desert Clip", "Thieves Attic", "Desert South Portal"),
("Thieves to Desert Clip", "Thieves Attic", "Desert East Portal"),
]
specrock_spots = [("Spec Rock Clip", "Spectacle Rock Cave (Peak)", "Spectacle Rock Cave (Top)")]
paradox_spots = [("Paradox Front Teleport", "Paradox Cave Front", "Paradox Cave Chest Area")]
# We need to make connectors at a separate time from the connections, because of how dungeons are linked to regions
kikiskip_connectors = [("Kiki Skip", "Spectacle Rock Cave (Bottom)", "Palace of Darkness Exit")]
mireheraswamp_connectors = [
("Mire to Hera Clip", "Mire Torches Top", "Tower of Hera Exit"),
("Mire to Hera Clip", "Mire Torches Top", "Swamp Palace Exit"),
]
thievesdesert_connectors = [
("Thieves to Desert Clip", "Thieves Attic", "Desert Palace Exit (West)"),
("Thieves to Desert Clip", "Thieves Attic", "Desert Palace Exit (South)"),
("Thieves to Desert Clip", "Thieves Attic", "Desert Palace Exit (East)"),
]
specrock_connectors = [
("Spec Rock Clip", "Spectacle Rock Cave (Peak)", "Spectacle Rock Cave Exit (Top)"),
("Spec Rock Clip", "Spectacle Rock Cave (Peak)", "Spectacle Rock Cave Exit"),
]
# Create connections between dungeons/locations
def create_hybridmajor_connections(world, player):
for spots in [
kikiskip_spots,
mireheraswamp_spots,
icepalace_spots,
thievesdesert_spots,
specrock_spots,
paradox_spots,
]:
create_no_logic_connections(player, world, spots)
# Turn dungeons into connectors
def create_hybridmajor_connectors(world, player):
for connectors in [
kikiskip_connectors,
mireheraswamp_connectors,
thievesdesert_connectors,
specrock_connectors,
]:
new_connectors = [(connector[0], connector[1], world.get_entrance(connector[2], player).connected_region) for connector in connectors]
create_no_logic_connections(player, world, new_connectors)
# For some entrances, we need to fake having pearl, because we're in fake DW/LW.
# This creates a copy of the input state that has Moon Pearl.
def fake_pearl_state(state, player):
if state.has("Moon Pearl", player):
return state
fake_state = state.copy()
fake_state.prog_items["Moon Pearl", player] += 1
return fake_state
# Sets the rules on where we can actually go using this clip.
# Behavior differs based on what type of ER shuffle we're playing.
def dungeon_reentry_rules(world, player, clip: Entrance, dungeon_region: str, dungeon_exit: str):
fix_dungeon_exits = world.fix_palaceofdarkness_exit[player]
fix_fake_worlds = world.fix_fake_world[player]
dungeon_entrance = [r for r in world.get_region(dungeon_region, player).entrances if r.name != clip.name][0]
if not fix_dungeon_exits: # vanilla, simple, restricted, dungeonssimple; should never have fake worlds fix
# Dungeons are only shuffled among themselves. We need to check SW, MM, and AT because they can't be reentered trivially.
# entrance doesn't exist until you fire rod it from the other side
if dungeon_entrance.name == "Skull Woods Final Section":
Rules.set_rule(clip, lambda state: False)
elif dungeon_entrance.name == "Misery Mire":
if world.swords[player] == "swordless":
Rules.add_rule(clip, lambda state: state.has_misery_mire_medallion(player))
else:
Rules.add_rule(clip, lambda state: state.has_sword(player) and state.has_misery_mire_medallion(player))
elif dungeon_entrance.name == "Agahnims Tower":
Rules.add_rule(
clip,
lambda state: state.has("Cape", player)
or state.has_beam_sword(player)
or state.has("Beat Agahnim 1", player),
)
# Then we set a restriction on exiting the dungeon, so you can't leave unless you got in normally.
Rules.add_rule(world.get_entrance(dungeon_exit, player), lambda state: dungeon_entrance.can_reach(state))
elif not fix_fake_worlds: # full, dungeonsfull; fixed dungeon exits, but no fake worlds fix
# Entry requires the entrance's requirements plus a fake pearl, but you don't gain logical access to the surrounding region.
Rules.add_rule(clip, lambda state: dungeon_entrance.access_rule(fake_pearl_state(state, player)))
# exiting restriction
Rules.add_rule(world.get_entrance(dungeon_exit, player), lambda state: dungeon_entrance.can_reach(state))
# Otherwise, the shuffle type is lean, lite, crossed, or insanity; all of these do not need additional rules on where we can go,
# since the clip links directly to the exterior region.
def underworld_glitches_rules(world, player):
# Ice Palace Entrance Clip, needs bombs or cane of somaria to exit bomb drop room
Rules.add_rule(
world.get_entrance("Ice Bomb Drop SE", player),
lambda state: state.can_dash_clip(world.get_region("Ice Lobby", player), player)
and (state.can_use_bombs(player) or state.has("Cane of Somaria", player)),
combine="or",
)
# Kiki Skip
kks = world.get_entrance("Kiki Skip", player)
Rules.set_rule(kks, lambda state: state.can_bomb_clip(kks.parent_region, player))
dungeon_reentry_rules(world, player, kks, "Palace of Darkness Portal", "Palace of Darkness Exit")
# Mire -> Hera -> Swamp
def mire_clip(state):
return state.can_reach("Mire Torches Top", "Region", player) and state.can_dash_clip(
world.get_region("Mire Torches Top", player), player
)
def hera_clip(state):
return state.can_reach("Hera 4F", "Region", player) and state.can_dash_clip(
world.get_region("Hera 4F", player), player
)
Rules.add_rule(
world.get_entrance("Hera Startile Corner NW", player),
lambda state: mire_clip(state) and state.has("Big Key (Misery Mire)", player),
combine="or",
)
Rules.add_rule(
world.get_location("Tower of Hera - Big Chest", player),
lambda state: mire_clip(state) and state.has("Big Key (Misery Mire)", player),
combine="or",
)
mire_to_hera = world.get_entrance("Mire to Hera Clip", player)
mire_to_swamp = world.get_entrance("Hera to Swamp Clip", player)
Rules.set_rule(mire_to_hera, mire_clip)
Rules.set_rule(mire_to_swamp, lambda state: mire_clip(state) and state.has("Flippers", player))
# Using the entrances for various ER types. Hera -> Swamp never matters because you can only logically traverse with the mire keys
dungeon_reentry_rules(world, player, mire_to_hera, "Hera Lobby", "Tower of Hera Exit")
dungeon_reentry_rules(world, player, mire_to_swamp, "Swamp Lobby", "Swamp Palace Exit")
# We need to set _all_ swamp doors to be openable with mire keys, otherwise the small key can't be behind them - 6 keys because of Pots
# Flippers required for all of these doors to prevent locks when flooding
for door in [
"Swamp Trench 1 Approach ES",
"Swamp Hammer Switch SW",
"Swamp Entrance Down Stairs",
"Swamp Pot Row WS",
"Swamp Trench 1 Key Ledge NW",
"Swamp Hub WN",
"Swamp Hub North Ledge N",
"Swamp Crystal Switch EN",
"Swamp Push Statue S",
"Swamp Waterway NW",
"Swamp T SW",
]:
Rules.add_rule(
world.get_entrance(door, player),
lambda state: mire_clip(state)
and state.has("Small Key (Misery Mire)", player, count=6)
and state.has("Flippers", player),
combine="or",
)
# Rules.add_rule(world.get_entrance(door, player), lambda state: mire_clip(state) and state.has('Flippers', player), combine="or")
Rules.add_rule(
world.get_location("Trench 1 Switch", player), lambda state: mire_clip(state) or hera_clip(state), combine="or"
)
# Build the rule for SP moat.
# We need to be able to s+q to old man, then go to either Mire or Hera at either Hera or GT.
# First we require a certain type of entrance shuffle, then build the rule from its pieces.
if not world.swamp_patch_required[player]:
if world.shuffle[player] in [
"vanilla",
"dungeonssimple",
"dungeonsfull",
"dungeonscrossed",
]:
rule_map = {
"Mire Portal": (lambda state: state.can_reach("Mire Torches Top", "Entrance", player)),
"Hera Portal": (lambda state: state.can_reach("Hera Startile Corner NW", "Entrance", player)),
}
inverted = world.mode[player] == "inverted"
def hera_rule(state):
return (state.has("Moon Pearl", player) or not inverted) and rule_map.get(
world.get_entrance("Tower of Hera", player).connected_region.name, lambda state: False
)(state)
def gt_rule(state):
return (state.has("Moon Pearl", player) or inverted) and rule_map.get(
world.get_entrance(("Ganons Tower"), player).connected_region.name, lambda state: False
)(state)
def mirrorless_moat_rule(state):
return (
state.can_reach("Old Man S&Q", "Entrance", player)
and state.has("Flippers", player)
and mire_clip(state)
and (hera_rule(state) or gt_rule(state))
)
Rules.add_rule(
world.get_entrance("Swamp Lobby Moat", player), lambda state: mirrorless_moat_rule(state), combine="or"
)
# Thieves -> Desert
Rules.add_rule(
world.get_entrance("Thieves to Desert Clip", player),
lambda state: state.can_dash_clip(world.get_region("Thieves Attic", player), player),
)
dungeon_reentry_rules(
world,
player,
world.get_entrance("Thieves to Desert Clip", player),
"Desert West Portal",
"Desert Palace Exit (West)",
)
dungeon_reentry_rules(
world,
player,
world.get_entrance("Thieves to Desert Clip", player),
"Desert South Portal",
"Desert Palace Exit (South)",
)
dungeon_reentry_rules(
world,
player,
world.get_entrance("Thieves to Desert Clip", player),
"Desert East Portal",
"Desert Palace Exit (East)",
)
# Collecting left chests in Paradox Cave using a dash clip -> dash citrus, 1f right, teleport up
paradox_left_chests = ["Paradox Cave Lower - Far Left", "Paradox Cave Lower - Left", "Paradox Cave Lower - Middle"]
for location in paradox_left_chests:
Rules.add_rule(
world.get_location(location, player),
lambda state: state.can_dash_clip(world.get_location(location, player).parent_region, player),
"or",
)
# Collecting right chests in Paradox Cave using a dash clip on left side -> dash citrus, 1f right, teleport up, then hitting the switch
paradox_right_chests = ["Paradox Cave Lower - Right", "Paradox Cave Lower - Far Right"]
for location in paradox_right_chests:
Rules.add_rule(
world.get_location(location, player),
lambda state: (
state.can_dash_clip(world.get_location(location, player).parent_region, player)
and state.can_hit_crystal(player)
),
"or",
)
+180 -152
View File
@@ -161,15 +161,22 @@ jsl.l OWWorldCheck16 : nop
org $02b16e ; AND #$3F : ORA 7EF3CA
and #$7f : eor #$40 : nop #2
org $06AD4C
jsl.l OWBonkDrops : nop #4
org $1EDE6F
jsl.l OWBonkGoodBeeDrop : bra +
org $09C3C4
jsl.l OWBonkDropPrepSprite : nop #2
org $09C801
jsl.l OWBonkDropPrepSprite : nop #2
org $06D052
jsl.l OWBonkDropSparkle
org $06AD49
jsl.l OWBonkDropsOverworld : nop
org $1EDE6A
jsl.l OWBonkDropSparkle : BNE GoldBee_Dormant_exit
jsl.l OWBonkDropsUnderworld : bra +
GoldBee_SpawnSelf_SetProperties:
phb : lda.b #$1E : pha : plb ; switch to bank 1E
jsr GoldBee_SpawnSelf+12
plb : rtl
nop #3
nop #2
+
;Code
@@ -408,7 +415,66 @@ LoadMapDarkOrMixed:
dw $0400+$0210 ; bottom right
}
OWBonkGoodBeeDrop:
OWBonkDropPrepSprite:
{
LDA.b $1B : BEQ +
LDA.w $0FB5 ; what we wrote over
PHA
BRA .continue
+
STZ.w $0F20,X : STZ.w $0E30,X ; what we wrote over
PHA
.continue
LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BEQ .return
+ LDA.w $0E20,X : CMP.b #$D9 : BNE +
LDA.b #$03 : STA.w $0F20,X
BRA .prep
+ CMP.b #$B2 : BEQ .prep
PLA : RTL
.prep
STZ.w !SPRITE_REDRAW,X
PHB : PHK : PLB : PHY
TXY : JSR OWBonkDropLookup : BCC .done
; found match ; X = rec + 1
INX : LDA.w OWBonkPrizeData,X : PHA
JSR OWBonkDropCollected : PLA : BCC .done
TYX : LDA.b #$01 : STA.w !SPRITE_REDRAW,X
.done
TYX : PLY : PLB
.return
PLA : RTL
}
OWBonkDropSparkle:
{
LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BEQ .nosparkle
LDA.w $0E90,X : BEQ .nosparkle
LDA.w !SPRITE_REDRAW,X : BNE .nosparkle
JSL Sprite_SpawnSparkleGarnish
; move sparkle down 1 tile
PHX : TYX : PLY
LDA.l $7FF81E,X : CLC : ADC.b #$10 : STA.l $7FF81E,X
LDA.l $7FF85A,X : ADC.b #$00 : STA.l $7FF85A,X
PHY : TXY : PLX
.nosparkle
LDA $0E20,X : CMP.b #$D9 : BEQ .greenrupee
CMP.b #$B2 : BEQ .goodbee
RTL
.goodbee
LDA $0E90,X ; what we wrote over
RTL
.greenrupee
JSL Sprite_DrawRippleIfInWater ; what we wrote over
RTL
}
OWBonkDropsUnderworld:
{
LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BNE .shuffled
.vanilla ; what we wrote over
@@ -416,20 +482,63 @@ OWBonkGoodBeeDrop:
LDA.l BottleContentsOne : ORA.l BottleContentsTwo
ORA.l BottleContentsThree : ORA.l BottleContentsFour
RTL
.shuffled
LDA.w $0DD0,X : BNE +
JMP .return+1
BRA .return+1
+ PHY : TXY
LDA.l RoomDataWRAM[$0120].high : AND.b #$02 : PHA : BNE + ; check if collected
LDA.b #$1B : STA $12F ; JSL Sound_SetSfx3PanLong ; seems that when you bonk, there is a pending bonk sfx, so we clear that out and replace with reveal secret sfx
+
LDA.l OWBonkPrizeTable[42].mw_player : BEQ + ; multiworld item
LDA.l OWBonkPrizeTable[42].loot
JMP .spawn_item
+
JSL OWBonkDrops
.determine_type ; S = Collected
LDA.l OWBonkPrizeTable[42].loot ; A = item id
.return
PLY
LDA #$08 ; makes original good bee not spawn
RTL
}
OWBonkDropsOverworld:
{
LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BNE .shuffled
BRA .vanilla
.shuffled
LDA.w $0DD0,Y : BNE +
BRA .vanilla
+ LDA.w $0E20,Y : CMP.b #$D9 : BEQ +
BRA .vanilla+3
+
LDA.b #$00 : STA.w $0F20,Y ; restore proper layer
JSL OWBonkDrops
.vanilla
LDA.w $0E20,Y : CMP.b #$D8 ; what we wrote over
RTL
}
OWBonkDrops:
{
PHB : PHK : PLB
LDA.b $1B : BEQ +
LDX.b #((UWBonkPrizeData-OWBonkPrizeData)+1)
BRA .found_match
+
JSR OWBonkDropLookup : BCS .found_match
JMP .return+2
.found_match
INX : LDA.w OWBonkPrizeData,X : PHX : PHA ; S = FlagBitmask, X (row + 2)
JSR OWBonkDropCollected : PHA : BCS .load_item_and_mw ; S = Collected, FlagBitmask, X (row + 2)
LDA.b #$1B : STA $12F ; JSL Sound_SetSfx3PanLong ; seems that when you bonk, there is a pending bonk sfx, so we clear that out and replace with reveal secret sfx
; JSLSpriteSFX_QueueSFX3WithPan
.load_item_and_mw
LDA 3,S : TAX : INX : LDA.w OWBonkPrizeData,X
PHA : INX : LDA.w OWBonkPrizeData,X : BEQ +
; multiworld item
DEX : PLA ; A = item id; X = row + 3
JMP .spawn_item
+ DEX : PLA ; A = item id; X = row + 3
.determine_type ; A = item id; X = row + 3; S = Collected, FlagBitmask, X (row + 2)
CMP.b #$B0 : BNE +
LDA.b #$79 : JMP .sprite_transform ; transform to bees
+ CMP.b #$42 : BNE +
@@ -461,140 +570,12 @@ OWBonkGoodBeeDrop:
LDA.b #$AC : BRA .sprite_transform ; transform to apples
+ CMP.b #$B2 : BNE +
LDA.b #$E3 : BRA .sprite_transform ; transform to fairy
+ CMP.b #$B3 : BNE .spawn_item
INX : INX : LDA.l OWBonkPrizeTable[42].vert_offset
CLC : ADC.b #$08 : PHA
LDA.w $0D00,Y : SEC : SBC.b 1,S : STA.w $0D00,Y
LDA.w $0D20,Y : SBC.b #$00 : STA.w $0D20,Y : PLX
LDA.b #$0B : SEC ; BRA .sprite_transform ; transform to chicken
.sprite_transform
JSL.l OWBonkSpritePrep
.mark_collected ; S = Collected
PLA : BNE +
LDA.l RoomDataWRAM[$0120].high : ORA.b #$02 : STA.l RoomDataWRAM[$0120].high
REP #$20
LDA.l TotalItemCounter : INC : STA.l TotalItemCounter
SEP #$20
+ BRA .return
; spawn itemget item
.spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : BRA .return
+ PHA
LDA.b #$01 : STA !FORCE_HEART_SPAWN
LDA.b #$EB : STA.l $7FFE00
JSL Sprite_SpawnDynamically+15 ; +15 to skip finding a new slot, use existing sprite
LDA.b #$01 : STA.w !SPRITE_REDRAW,Y
PLA : STA.w $0E80,Y
; affects the rate the item moves in the Y/X direction
LDA.b #$00 : STA.w $0D40,Y
LDA.b #$0A : STA.w $0D50,Y
LDA.b #$1A : STA.w $0F80,Y ; amount of force (gives height to the arch)
LDA.b #$FF : STA.w $0B58,Y ; stun timer
LDA.b #$30 : STA.w $0F10,Y ; aux delay timer 4 ?? dunno what that means
LDA.b #$00 : STA.w $0F20,Y ; layer the sprite is on
; sets the tile type that is underneath the sprite, water
TYX : LDA.b #$09 : STA.l $7FF9C2,X ; TODO: Figure out how to get the game to set this
; sets OW event bitmask flag, uses free RAM
LDA.l OWBonkPrizeTable[42].flag : STA.w $0ED0,Y
; determines the initial spawn point of item
LDA.w $0D00,Y : SEC : SBC.l OWBonkPrizeTable[42].vert_offset : STA.w $0D00,Y
LDA.w $0D20,Y : SBC #$00 : STA.w $0D20,Y
.return
PLY
LDA #$08 ; makes original good bee not spawn
RTL
}
; Y = sprite slot index of bonk sprite
OWBonkDrops:
{
CMP.b #$D8 : BEQ +
RTL
+ LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BNE +
JSL.l Sprite_TransmuteToBomb : RTL
+ LDA.w $0DD0,Y : BNE +
RTL
+
; loop thru rando bonk table to find match
PHB : PHK : PLB
LDA.b $8A
LDX.b #(41*6) ; 41 bonk items, 6 bytes each
- CMP.w OWBonkPrizeData,X : BNE +
INX
LDA.w $0D10,Y : LSR A : LSR A : LSR A : LSR A
EOR.w $0D00,Y : CMP.w OWBonkPrizeData,X : BNE ++ ; X = row + 1
BRA .found_match
++ DEX : LDA.b $8A
+ CPX.b #$00 : BNE +
PLB : RTL
+ DEX : DEX : DEX : DEX : DEX : DEX : BRA -
.found_match
INX : LDA.w OWBonkPrizeData,X : PHX : PHA ; S = FlagBitmask, X (row + 2)
LDX.b $8A : LDA.l OverworldEventDataWRAM,X : AND 1,S : PHA : BNE + ; S = Collected, FlagBitmask, X (row + 2)
LDA.b #$1B : STA $12F ; JSL Sound_SetSfx3PanLong ; seems that when you bonk, there is a pending bonk sfx, so we clear that out and replace with reveal secret sfx
+
LDA 3,S : TAX : INX : LDA.w OWBonkPrizeData,X
PHA : INX : LDA.w OWBonkPrizeData,X : BEQ +
; multiworld item
DEX : PLA ; X = row + 3
JMP .spawn_item
+ DEX : PLA ; X = row + 3
.determine_type ; A = item id ; S = Collected, FlagBitmask, X (row + 2)
CMP.b #$B0 : BNE +
LDA.b #$79 : JMP .sprite_transform ; transform to bees
+ CMP.b #$42 : BNE +
JSL.l Sprite_TransmuteToBomb ; transform a heart to bomb, vanilla behavior
JMP .mark_collected
+ CMP.b #$34 : BNE +
LDA.b #$D9 : CLC : JMP .sprite_transform ; transform to single rupee
+ CMP.b #$35 : BNE +
LDA.b #$DA : CLC : JMP .sprite_transform ; transform to blue rupee
+ CMP.b #$36 : BNE +
LDA.b #$DB : CLC : BRA .sprite_transform ; transform to red rupee
+ CMP.b #$27 : BNE +
LDA.b #$DC : CLC : BRA .sprite_transform ; transform to 1 bomb
+ CMP.b #$28 : BNE +
LDA.b #$DD : CLC : BRA .sprite_transform ; transform to 4 bombs
+ CMP.b #$31 : BNE +
LDA.b #$DE : CLC : BRA .sprite_transform ; transform to 8 bombs
+ CMP.b #$45 : BNE +
LDA.b #$DF : CLC : BRA .sprite_transform ; transform to small magic
+ CMP.b #$B4 : BNE +
LDA.b #$E0 : CLC : BRA .sprite_transform ; transform to big magic
+ CMP.b #$B5 : BNE +
LDA.b #$79 : JSL.l OWBonkSpritePrep
JSL.l GoldBee_SpawnSelf_SetProperties ; transform to good bee
BRA .mark_collected
+ CMP.b #$44 : BNE +
LDA.b #$E2 : CLC : BRA .sprite_transform ; transform to 10 arrows
+ CMP.b #$B1 : BNE +
LDA.b #$AC : BRA .sprite_transform ; transform to apples
+ CMP.b #$B2 : BNE +
LDA.b #$E3 : BRA .sprite_transform ; transform to fairy
+ CMP.b #$B3 : BNE .spawn_item
INX : INX : LDA.w OWBonkPrizeData,X ; X = row + 5
CLC : ADC.b #$08 : PHA
LDA.w $0D00,Y : SEC : SBC.b 1,S : STA.w $0D00,Y
LDA.w $0D20,Y : SBC.b #$00 : STA.w $0D20,Y : PLX
LDA.b #$0B : SEC ; BRA .sprite_transform ; transform to chicken
LDA.b #$0B ; BRA .sprite_transform ; transform to chicken
.sprite_transform
JSL.l OWBonkSpritePrep
@@ -602,16 +583,22 @@ OWBonkDrops:
.mark_collected ; S = Collected, FlagBitmask, X (row + 2)
PLA : BNE + ; S = FlagBitmask, X (row + 2)
TYX : JSL Sprite_IsOnscreen : BCC +
LDA.b $1B : BEQ ++
LDA.l RoomDataWRAM[$0120].high : ORA 1,S : STA.l RoomDataWRAM[$0120].high
LDA.w $0400 : ORA 1,S : STA.w $0400
BRA .increment_collection
++
LDX.b $8A : LDA.l OverworldEventDataWRAM,X : ORA 1,S : STA.l OverworldEventDataWRAM,X
.increment_collection
REP #$20
LDA.l TotalItemCounter : INC : STA.l TotalItemCounter
SEP #$20
+ JMP .return
+ BRA .return
; spawn itemget item
.spawn_item ; A = item id ; Y = tree sprite slot ; S = Collected, FlagBitmask, X (row + 2)
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : JMP .return ; S = FlagBitmask, X (row + 2)
.spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected, FlagBitmask, X (row + 2)
PLX : BEQ + : LDA.b #$00 : STA.w $0DD0,Y : BRA .return ; S = FlagBitmask, X (row + 2)
+ PHA
LDA.b #$01 : STA !FORCE_HEART_SPAWN
@@ -633,7 +620,12 @@ OWBonkDrops:
LDA.b #$00 : STA.w $0F20,Y ; layer the sprite is on
; sets OW event bitmask flag, uses free RAM
LDA.b $1B : BEQ +
; sets the tile type that is underneath the sprite, water
TYX : LDA.b #$09 : STA.l $7FF9C2,X ; TODO: Figure out how to get the game to set this
+
; sets bitmask flag, uses free RAM
PLA : STA.w $0ED0,Y ; S = X (row + 2)
; determines the initial spawn point of item
@@ -641,10 +633,44 @@ OWBonkDrops:
LDA.w $0D00,Y : SEC : SBC.w OWBonkPrizeData,X : STA.w $0D00,Y
LDA.w $0D20,Y : SBC #$00 : STA.w $0D20,Y
PLB : RTL
BRA .return+2
.return
PLA : PLA : PLB : RTL
PLA : PLA : PLB
RTL
}
; Y = sprite slot; returns X = row + 1
OWBonkDropLookup:
{
; loop thru rando bonk table to find match
LDA.b $8A
LDX.b #((UWBonkPrizeData-OWBonkPrizeData)-sizeof(OWBonkPrizeTable)) ; 41 bonk items, 6 bytes each
- CMP.w OWBonkPrizeData,X : BNE +
INX
LDA.w $0D10,Y : LSR A : LSR A : LSR A : LSR A
EOR.w $0D00,Y : CMP.w OWBonkPrizeData,X : BNE ++ ; X = row + 1
SEC : RTS
++ DEX : LDA.b $8A
+ CPX.b #$00 : BNE +
CLC : RTS
+ DEX : DEX : DEX : DEX : DEX : DEX : BRA -
}
; S = FlagBitmask ; returns SEC if collected
OWBonkDropCollected:
{
; check if collected
CLC
LDA.b $1B : BEQ +
LDA.l RoomDataWRAM[$0120].high : AND.b 3,S : BEQ .return ; S = Collected, FlagBitmask, X (row + 2)
SEC : RTS
+
LDX.b $8A : LDA.l OverworldEventDataWRAM,X : AND 3,S : BEQ .return ; S = Collected, FlagBitmask, X (row + 2)
SEC : RTS
.return
RTS
}
; A = SpriteID, Y = Sprite Slot Index, X = free/overwritten
@@ -1717,7 +1743,7 @@ db $18, $a8, $10, $b2, $00, $20
db $18, $36, $08, $35, $00, $20
db $1a, $8a, $10, $42, $00, $20
db $1a, $1d, $08, $b2, $00, $20
db $ff, $77, $04, $35, $00, $20 ; pre aga ONLY ; hijacked murahdahla bonk tree
;db $1a, $77, $04, $35, $00, $20 ; pre aga ONLY ; hijacked murahdahla bonk tree
db $1b, $46, $10, $b1, $00, $10
db $1d, $6b, $10, $b1, $00, $20
db $1e, $72, $10, $b2, $00, $20
@@ -1728,6 +1754,7 @@ db $2e, $9c, $10, $b2, $00, $20
db $2e, $b4, $08, $b0, $00, $20
db $32, $29, $10, $42, $00, $20
db $32, $9a, $08, $b2, $00, $20
;db $34, $xx, $10, $xx, $00, $1c ; pre aga ONLY
db $42, $66, $10, $b2, $00, $20
db $51, $08, $10, $b2, $00, $04
db $51, $09, $08, $b2, $00, $04
@@ -1743,6 +1770,7 @@ db $6e, $8c, $10, $35, $00, $10
db $6e, $90, $08, $b0, $00, $10
db $6e, $a4, $04, $b1, $00, $10
db $74, $4e, $10, $b1, $00, $1c
UWBonkPrizeData:
db $ff, $00, $02, $b5, $00, $08
; temporary fix - murahdahla replaces one of the bonk tree prizes
Binary file not shown.
+5 -1
View File
@@ -6,6 +6,10 @@ This can also be used to roll a mystery or mutli-mystery seed via the GUI. [Exam
The cli includes a couple arguments to help:
`--print_template_yaml` will create a yaml file based on the settings used. This does not contain any seed specific information.
Present on the GUI as `Export Yaml` on the bottom.
`--print_custom_yaml` will create a yaml file based on the seed rolled. Treat it like a spoiler.
`--customizer` takes a file as an argument.
@@ -44,7 +48,7 @@ Start inventory is not supported here. It has a separate section.
###### Not Yet Implemented
Rom/Adjust flags like sprite, quickswap are not outputing with the print_custom_yaml settings
Rom/Adjust flags like sprite, quickswap are not outputing with the print_template_yaml or print_custom_yaml settings
### item_pool
+9 -4
View File
@@ -23,6 +23,7 @@
"noglitches",
"minorglitches",
"owglitches",
"hybridglitches",
"nologic"
]
},
@@ -575,11 +576,15 @@
"action": "store_true",
"type": "bool"
},
"saveonexit": {
"aga_randomness": {
"action": "store_false",
"type": "bool"
},
"settingsonload": {
"choices": [
"ask",
"always",
"never"
"default",
"saved",
"lastused"
]
},
"outputname": {},
+10 -7
View File
@@ -2,7 +2,7 @@
"cli": {
"yes": "Yes",
"no": "No",
"app.title": "ALttP Door Randomizer Version %s : --seed %s --code %s",
"app.title": "ALttP Overworld Randomizer Version %s : --seed %s --code %s",
"version": "Version",
"seed": "Seed",
"player": "Player",
@@ -56,7 +56,8 @@
"building.collection.spheres": "Building up collection spheres",
"building.calculating.spheres": "Calculated sphere %i, containing %i of %i progress items.",
"building.final.spheres": "Calculated final sphere %i, containing %i of %i progress items.",
"old.python.version": "Door Rando may have issues with python versions earlier than 3.7. Detected version: %s"
"old.python.version": "Door Rando may have issues with python versions earlier than 3.7. Detected version: %s",
"hybridglitches.door.shuffle": "Hybrid Major Glitches is not currently compatible with Door Shuffle."
},
"help": {
"lang": [ "App Language, if available, defaults to English" ],
@@ -64,11 +65,13 @@
"bps": [ "Output BPS patches instead of ROMs"],
"logic": [
"Select Enforcement of Item Requirements. (default: %(default)s)",
"No Glitches: No Glitch knowledge required.",
"Minor Glitches: May require Fake Flippers, Bunny Revival",
" and Dark Room Navigation.",
"No Logic: Distribute items without regard for",
" item requirements."
"No Glitches: No Glitch knowledge required.",
"Minor Glitches: May require Fake Flippers, Bunny Revival",
" and Dark Room Navigation.",
"Overworld Glitches: May require overworld clips and teleports.",
"Hybrid Major Glitches: May require underworld clips.",
"No Logic: Distribute items without regard for",
" item requirements."
],
"mode": [
"Select game mode. (default: %(default)s)",
+8 -5
View File
@@ -236,10 +236,10 @@
"randomizer.generation.calcplaythrough": "Calculate Playthrough",
"randomizer.generation.print_custom_yaml": "Print Customizer File",
"randomizer.generation.saveonexit": "Save Settings on Exit",
"randomizer.generation.saveonexit.ask": "Ask Me",
"randomizer.generation.saveonexit.always": "Always",
"randomizer.generation.saveonexit.never": "Never",
"randomizer.generation.settingsonload": "Settings On Load",
"randomizer.generation.settingsonload.default": "Default",
"randomizer.generation.settingsonload.saved": "Saved",
"randomizer.generation.settingsonload.lastused": "Last Used",
"randomizer.generation.rom": "Base Rom: ",
"randomizer.generation.rom.button": "Select Rom",
@@ -263,6 +263,7 @@
"randomizer.item.logiclevel.noglitches": "No Glitches",
"randomizer.item.logiclevel.minorglitches": "Minor Glitches",
"randomizer.item.logiclevel.owglitches": "Overworld Glitches",
"randomizer.item.logiclevel.hybridglitches": "Hybrid Major Glitches",
"randomizer.item.logiclevel.nologic": "No Logic",
"randomizer.item.goal": "Goal",
@@ -389,10 +390,12 @@
"bottom.content.names": "Player names",
"bottom.content.seed": "Seed #",
"bottom.content.generationcount": "Count",
"bottom.content.go": "Generate Patched Rom",
"bottom.content.go": "Generate Game",
"bottom.content.exportyaml": "Export Yaml",
"bottom.content.dialog.error": "Error while creating seed",
"bottom.content.dialog.success": "Success",
"bottom.content.dialog.success.message": "Rom created successfully.",
"bottom.content.savesettings": "Save Settings",
"bottom.content.outputdir": "Select Destination",
"bottom.content.docs": "Open Documentation"
}
@@ -1,11 +1,11 @@
{
"widgets": {
"saveonexit": {
"settingsonload": {
"type": "selectbox",
"options": [
"ask",
"always",
"never"
"default",
"saved",
"lastused"
]
}
}
@@ -21,6 +21,7 @@
"noglitches",
"minorglitches",
"owglitches",
"hybridglitches",
"nologic"
]
},
+37 -20
View File
@@ -48,11 +48,13 @@ class CustomSettings(object):
meta = defaultdict(lambda: None, self.file_source['meta'])
return meta['players']
def adjust_args(self, args):
def adjust_args(self, args, resolve_weighted=True):
def get_setting(value: Any, default):
if value or value == 0:
if isinstance(value, dict):
return random.choices(list(value.keys()), list(value.values()), k=1)[0]
if resolve_weighted:
return random.choices(list(value.keys()), list(value.values()), k=1)[0]
return None
else:
return value
return default
@@ -147,8 +149,8 @@ class CustomSettings(object):
args.mapshuffle[p] = True
args.compassshuffle[p] = True
args.shufflebosses[p] = get_setting(settings['boss_shuffle'], args.shufflebosses[p])
args.shuffleenemies[p] = get_setting(settings['enemy_shuffle'], args.shuffleenemies[p])
args.shufflebosses[p] = get_setting(settings['boss_shuffle'], get_setting(settings['shufflebosses'], args.shufflebosses[p]))
args.shuffleenemies[p] = get_setting(settings['enemy_shuffle'], get_setting(settings['shuffleenemies'], args.shuffleenemies[p]))
args.enemy_health[p] = get_setting(settings['enemy_health'], args.enemy_health[p])
args.enemy_damage[p] = get_setting(settings['enemy_damage'], args.enemy_damage[p])
args.shufflepots[p] = get_setting(settings['shufflepots'], args.shufflepots[p])
@@ -167,6 +169,7 @@ class CustomSettings(object):
args.triforce_min_difference[p] = get_setting(settings['triforce_min_difference'], args.triforce_min_difference[p])
args.triforce_max_difference[p] = get_setting(settings['triforce_max_difference'], args.triforce_max_difference[p])
args.beemizer[p] = get_setting(settings['beemizer'], args.beemizer[p])
args.aga_randomness[p] = get_setting(settings['aga_randomness'], args.aga_randomness[p])
# mystery usage
args.usestartinventory[p] = get_setting(settings['usestartinventory'], args.usestartinventory[p])
@@ -262,10 +265,11 @@ class CustomSettings(object):
self.world_rep['meta'] = meta_dict
meta_dict['players'] = world.players
meta_dict['algorithm'] = world.algorithm
meta_dict['seed'] = world.seed
meta_dict['race'] = settings.race
meta_dict['user_notes'] = settings.notes
self.world_rep['settings'] = settings_dict
if world.precollected_items:
self.world_rep['start_inventory'] = start_inv = {}
for p in self.player_range:
settings_dict[p] = {}
settings_dict[p]['ow_shuffle'] = world.owShuffle[p]
@@ -310,8 +314,8 @@ class CustomSettings(object):
settings_dict[p]['keyshuffle'] = world.keyshuffle[p]
settings_dict[p]['mapshuffle'] = world.mapshuffle[p]
settings_dict[p]['compassshuffle'] = world.compassshuffle[p]
settings_dict[p]['shufflebosses'] = world.boss_shuffle[p]
settings_dict[p]['shuffleenemies'] = world.enemy_shuffle[p]
settings_dict[p]['boss_shuffle'] = world.boss_shuffle[p]
settings_dict[p]['enemy_shuffle'] = world.enemy_shuffle[p]
settings_dict[p]['enemy_health'] = world.enemy_health[p]
settings_dict[p]['enemy_damage'] = world.enemy_damage[p]
settings_dict[p]['shufflepots'] = world.potshuffle[p]
@@ -323,6 +327,11 @@ class CustomSettings(object):
settings_dict[p]['triforce_goal'] = world.treasure_hunt_count[p]
settings_dict[p]['triforce_pool'] = world.treasure_hunt_total[p]
settings_dict[p]['beemizer'] = world.beemizer[p]
settings_dict[p]['aga_randomness'] = world.aga_randomness[p]
if world.precollected_items:
start_inv[p] = []
for item in world.precollected_items:
start_inv[item.player].append(item.name)
# rom adjust stuff
# settings_dict[p]['sprite'] = world.sprite[p]
@@ -335,34 +344,42 @@ class CustomSettings(object):
# settings_dict[p]['ow_palettes'] = world.ow_palettes[p]
# settings_dict[p]['uw_palettes'] = world.uw_palettes[p]
# settings_dict[p]['shuffle_sfx'] = world.shuffle_sfx[p]
# settings_dict[p]['shuffle_songinstruments'] = world.shuffle_songinstruments[p]
# more settings?
def record_info(self, world):
self.world_rep['meta']['seed'] = world.seed
self.world_rep['bosses'] = bosses = {}
self.world_rep['start_inventory'] = start_inv = {}
self.world_rep['medallions'] = medallions = {}
for p in self.player_range:
bosses[p] = {}
start_inv[p] = []
medallions[p] = {}
for dungeon in world.dungeons:
for level, boss in dungeon.bosses.items():
location = dungeon.name if level is None else f'{dungeon.name} ({level})'
if boss and 'Agahnim' not in boss.name:
bosses[dungeon.player][location] = boss.name
for item in world.precollected_items:
start_inv[item.player].append(item.name)
def record_item_pool(self, world):
self.world_rep['item_pool'] = item_pool = {}
self.world_rep['medallions'] = medallions = {}
for p in self.player_range:
item_pool[p] = defaultdict(int)
medallions[p] = {}
for item in world.itempool:
item_pool[item.player][item.name] += 1
for p, req_medals in world.required_medallions.items():
medallions[p]['Misery Mire'] = req_medals[0]
medallions[p]['Turtle Rock'] = req_medals[1]
def record_item_pool(self, world, use_custom_pool=False):
if not use_custom_pool or world.custom:
self.world_rep['item_pool'] = item_pool = {}
for p in self.player_range:
if not use_custom_pool or p in world.customitemarray:
item_pool[p] = defaultdict(int)
if use_custom_pool and world.custom:
import source.classes.constants as CONST
for p in world.customitemarray:
for i, c in world.customitemarray[p].items():
if c > 0:
item = CONST.CUSTOMITEMLABELS[CONST.CUSTOMITEMS.index(i)]
item_pool[p][item] += c
else:
for item in world.itempool:
item_pool[item.player][item.name] += 1
def record_item_placements(self, world):
self.world_rep['placements'] = placements = {}
for p in self.player_range:
+28 -28
View File
@@ -337,10 +337,10 @@ spc_instruments = { # table @ $19FB1C
0x02: SPCInstrument("Timpani", 0x02, [0xFF, 0xE0], 0xB8, 0x09C0).beat(),
0x03: SPCInstrument("Square Wave", 0x03, [0xFF, 0xE0], 0xB8, 0x0400).bass().mel(),
0x04: SPCInstrument("Saw Wave", 0x04, [0xFF, 0xE0], 0xB8, 0x0400).bass(),
0x05: SPCInstrument("Clink", 0x05, [0xFF, 0xE0], 0xB8, 0x0470).amb(),
0x05: SPCInstrument("Clink", 0x05, [0xFF, 0xE0], 0xB8, 0x0470),
0x06: SPCInstrument("Wobbly Lead", 0x06, [0xFF, 0xE0], 0xB8, 0x0470).amb(),
0x07: SPCInstrument("Compound Saw", 0x07, [0xFF, 0xE0], 0xB8, 0x0470),
0x08: SPCInstrument("Tweet", 0x08, [0xFF, 0xE0], 0xB8, 0x07A0).amb(),
0x08: SPCInstrument("Tweet", 0x08, [0xFF, 0xE0], 0xB8, 0x07A0).amb().beat(),
0x09: SPCInstrument("Strings A", 0x09, [0x8F, 0xE9], 0xB8, 0x01E0).mel().bass(True),
0x0A: SPCInstrument("Strings B", 0x0A, [0x8A, 0xE9], 0xB8, 0x01E0).mel().bass(True),
0x0B: SPCInstrument("Trombone", 0x0B, [0xFF, 0xE0], 0xB8, 0x0300).mel().bass(True).beat(),
@@ -468,7 +468,7 @@ spc_instrument_changes = [
0x02: [0x1ABBE6],
0x03: [0x1ABC0B]}, 0x09),
InstrumentChange(0x07, 0x00, {0x04: [0x1ABB53, 0x1AB8C9]}, 0x16),
InstrumentChange(0x07, 0x01, {0x04: [0x1AB8E6]}, 0x0E, type=Am|Me|Rh, ban=[0x06]),
InstrumentChange(0x07, 0x01, {0x04: [0x1AB8E6]}, 0x0E, type=Am|Me|Rh, ban=[0x01, 0x05, 0x06, 0x17]),
InstrumentChange(0x07, 0x01, {0x05: [0x1AB8EB]}, 0x0A),
InstrumentChange(0x07, 0x02, {0x04: [0x1AB981]}, 0x16),
InstrumentChange(0x07, 0x03, {0x02: [0x1ABC37],
@@ -486,7 +486,7 @@ spc_instrument_changes = [
InstrumentChange(0x07, 0x06, {0x05: [0x1ABCE6]}, 0x0A),
InstrumentChange(0x08, 0x00, {0x00: [0x1ABD3A],
0x01: [0x1ABD5B]}, 0x06, type=Me|Rh|Am),
0x01: [0x1ABD5B]}, 0x06, type=Me|Rh|Am, ban=[0x05]),
InstrumentChange(0x08, 0x00, {0x02: [0x1ABD70],
0x05: [0x1ABE06]}, 0x0F),
InstrumentChange(0x08, 0x00, {0x03: [0x1ABDAC]}, 0x0A),
@@ -495,22 +495,22 @@ spc_instrument_changes = [
InstrumentChange(0x09, 0x00, {0x00: [0x1AC25A],
0x05: [0x1AC28E]}, 0x0A),
InstrumentChange(0x09, 0x00, {0x01: [0x1AC26E]}, 0x14),
InstrumentChange(0x09, 0x01, {0x01: [0x1ABF0A]}, 0x14),
InstrumentChange(0x09, 0x00, {0x01: [0x1AC26E]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x01, {0x01: [0x1ABF0A]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x01, {0x06: [0x1ABF43]}, 0x09),
InstrumentChange(0x09, 0x02, {0x00: [0x1AC450],
0x05: [0x1AC56D],
0x07: [0x1AC595]}, 0x0A),
InstrumentChange(0x09, 0x02, {0x01: [0x1AC2AF]}, 0x14),
InstrumentChange(0x09, 0x02, {0x01: [0x1AC2AF]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x02, {0x03: [0x1AC4B3],
0x04: [0x1AC510]}, 0x11),
InstrumentChange(0x09, 0x02, {0x06: [0x1AC2E9]}, 0x09),
InstrumentChange(0x09, 0x03, {0x00: [0x1ABF63]}, 0x0A),
InstrumentChange(0x09, 0x03, {0x01: [0x1ABF80]}, 0x14),
InstrumentChange(0x09, 0x03, {0x01: [0x1ABF80]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x03, {0x03: [0x1ABFA4]}, 0x11),
InstrumentChange(0x09, 0x03, {0x05: [0x1AC01C]}, 0x16),
InstrumentChange(0x09, 0x04, {0x00: [0x1AC04D]}, 0x0A),
InstrumentChange(0x09, 0x04, {0x01: [0x1AC05D]}, 0x14),
InstrumentChange(0x09, 0x04, {0x01: [0x1AC05D]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x04, {0x02: [0x1AC5CF]}, 0x18),
InstrumentChange(0x09, 0x04, {0x03: [0x1AC085],
0x04: [0x1AC5ED]}, 0x11),
@@ -518,20 +518,20 @@ spc_instrument_changes = [
InstrumentChange(0x09, 0x04, {0x06: [0x1AC146]}, 0x12),
InstrumentChange(0x09, 0x05, {0x00: [0x1AC178],
0x07: [0x1AC229]}, 0x0A),
InstrumentChange(0x09, 0x05, {0x01: [0x1AC196]}, 0x14),
InstrumentChange(0x09, 0x05, {0x01: [0x1AC196]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x05, {0x02: [0x1AC19E]}, 0x18),
InstrumentChange(0x09, 0x05, {0x03: [0x1AC1D3],
0x04: [0x1AC1F4]}, 0x12),
InstrumentChange(0x09, 0x06, {0x00: [0x1AC317],
0x07: [0x1AC3ED]}, 0x0A),
InstrumentChange(0x09, 0x06, {0x01: [0x1AC332]}, 0x14),
InstrumentChange(0x09, 0x06, {0x01: [0x1AC332]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x06, {0x02: [0x1AC33A]}, 0x18),
InstrumentChange(0x09, 0x06, {0x03: [0x1AC36F],
0x04: [0x1AC3A4],
0x05: [0x1AC3D9]}, 0x12),
InstrumentChange(0x09, 0x07, {0x00: [0x1AC40A],
0x05: [0x1AC43C]}, 0x0A),
InstrumentChange(0x09, 0x07, {0x01: [0x1AC41C]}, 0x14),
InstrumentChange(0x09, 0x07, {0x01: [0x1AC41C]}, 0x14, type=Am|Be, ban=[0x05, 0x06]),
InstrumentChange(0x09, 0x07, {0x02: [0x1AC492]}, 0x18),
InstrumentChange(0x09, 0x07, {0x03: [0x1AC680],
0x04: [0x1AC6C1]}, 0x11),
@@ -563,21 +563,21 @@ spc_instrument_changes = [
0x05: [0x1AC87E]}, 0x0B),
InstrumentChange(0x0C, 0x01, {0x02: [0x1AC89A],
0x03: [0x1AC8AD]}, 0x11),
InstrumentChange(0x0C, 0x01, {0x04: [0x1AC8B7]}, 0x0E),
InstrumentChange(0x0C, 0x01, {0x04: [0x1AC8B7]}, 0x0E, type=Rh|Am, ban=[0x05]),
InstrumentChange(0x0C, 0x01, {0x05: [0x1AC8C3]}, 0x02),
InstrumentChange(0x0C, 0x02, {0x02: [0x1AC8E0],
0x03: [0x1AC8F3]}, 0x11),
InstrumentChange(0x0C, 0x02, {0x04: [0x1AC8FD]}, 0x0E),
InstrumentChange(0x0C, 0x02, {0x04: [0x1AC8FD]}, 0x0E, type=Rh|Am, ban=[0x05]),
InstrumentChange(0x0C, 0x02, {0x05: [0x1AC909]}, 0x02),
InstrumentChange(0x0D, 0x00, {0x00: [0x1AD003],
0x03: [0x1AD02C],
0x04: [0x1AD03A]}, 0x11),
InstrumentChange(0x0D, 0x00, {0x01: [0x1AD010]}, 0x02),
InstrumentChange(0x0D, 0x00, {0x01: [0x1AD010]}, 0x02, type=Am|Be, ban=[0x01, 0x05, 0x06, 0x10, 0x17]),
InstrumentChange(0x0D, 0x00, {0x02: [0x1AD07F]}, 0x14),
InstrumentChange(0x0D, 0x01, {0x00: [0x1ACD10],
0x04: [0x1ACD9A]}, 0x0B),
InstrumentChange(0x0D, 0x01, {0x01: [0x1ACD41]}, 0x02),
InstrumentChange(0x0D, 0x01, {0x01: [0x1ACD41]}, 0x02, type=Am|Be, ban=[0x01, 0x05, 0x06, 0x10, 0x17]),
InstrumentChange(0x0D, 0x01, {0x03: [0x1ACD7F],
0x05: [0x1ACDCA]}, 0x11),
InstrumentChange(0x0D, 0x03, {0x00: [0x1ACE8E],
@@ -585,7 +585,7 @@ spc_instrument_changes = [
InstrumentChange(0x0D, 0x03, {0x02: [0x1ACED4]}, 0x14),
InstrumentChange(0x0D, 0x03, {0x03: [0x1ACEE0],
0x04: [0x1ACF07]}, 0x11),
InstrumentChange(0x0D, 0x04, {0x05: [0x1ACFE3]}, 0x02),
InstrumentChange(0x0D, 0x04, {0x05: [0x1ACFE3]}, 0x02, type=Am|Be, ban=[0x01, 0x05, 0x06, 0x10, 0x17]),
InstrumentChange(0x0E, 0x00, {0x00: [0x1AD29C]}, 0x16),
InstrumentChange(0x0E, 0x00, {0x01: [0x1AD2AD],
@@ -710,7 +710,7 @@ spc_instrument_changes = [
InstrumentChange(0x13, 0x00, {0x06: [0x1B9650],
0x07: [0x1B9696]}, 0x0F),
InstrumentChange(0x13, 0x00, {0x06: [0x1B967B],
0x07: [0x1B96C0]}, 0x02),
0x07: [0x1B96C0]}, 0x02, ban=[0x0B]),
InstrumentChange(0x14, 0x00, {0x00: [0x1B9901, 0x1B97A8]}, 0x15),
InstrumentChange(0x14, 0x01, {0x01: [0x1B97C4],
@@ -723,13 +723,13 @@ spc_instrument_changes = [
0x01: [0x1B9A50],
0x02: [0x1B9A6D],
0x03: [0x1B9A8A]}, 0x0B),
InstrumentChange(0x15, 0x00, {0x04: [0x1B9AA0]}, 0x02),
InstrumentChange(0x15, 0x01, {0x00: [0x1B9971]}, 0x02),
InstrumentChange(0x15, 0x00, {0x04: [0x1B9AA0]}, 0x02, type=Am|Be, ban=[0x01, 0x05, 0x10]),
InstrumentChange(0x15, 0x01, {0x00: [0x1B9971]}, 0x02, type=Am|Be, ban=[0x01, 0x05, 0x10]),
InstrumentChange(0x15, 0x01, {0x01: [0x1B9984],
0x02: [0x1B99AA],
0x03: [0x1B99D7]}, 0x0B),
InstrumentChange(0x15, 0x01, {0x04: [0x1B9A04]}, 0x14),
InstrumentChange(0x15, 0x02, {0x00: [0x1B9B45]}, 0x02),
InstrumentChange(0x15, 0x02, {0x00: [0x1B9B45]}, 0x02, type=Am|Be, ban=[0x01, 0x05, 0x10]),
InstrumentChange(0x15, 0x02, {0x01: [0x1B9B58],
0x02: [0x1B9B7E],
0x03: [0x1B9BAB]}, 0x0B),
@@ -749,10 +749,10 @@ spc_instrument_changes = [
0x05: [0x1B9EE4]}, 0x09),
InstrumentChange(0x17, 0x00, {0x00: [0x1BA287],
0x03: [0x1BA26A]}, 0x0E, type=Am|Rh, ban=[0x01, 0x05, 0x06, 0x10, 0x17]),
0x03: [0x1BA26A]}, 0x0E, type=[0x0E, 0x0F, 0x18]),
InstrumentChange(0x17, 0x01, {0x01: [0x1BA20F],
0x02: [0x1BA231],
0x03: [0x1BA24F]}, 0x0E, type=Am|Rh, ban=[0x01, 0x05, 0x06, 0x10]),
0x03: [0x1BA24F]}, 0x0E, type=Rh, ban=[0x0B, 0x0D, 0x16]),
InstrumentChange(0x17, 0x01, {0x02: [0x1BA231]}, 0x0F),
InstrumentChange(0x19, 0x00, {0x00: [0x1BA476],
0x01: [0x1BA49C],
@@ -775,7 +775,7 @@ spc_instrument_changes = [
0x04: [0x1BA783],
0x05: [0x1BA7A2],
0x06: [0x1BA7B9],
0x07: [0x1BA7D0]}, 0x0E),
0x07: [0x1BA7D0]}, 0x0E, type=Rh|Am, ban=[0x01, 0x05, 0x06, 0x10]),
InstrumentChange(0x1A, 0x01, {0x00: [0x1BA5C1],
0x05: [0x1BA68F],
0x06: [0x1BA6A6],
@@ -820,8 +820,8 @@ spc_instrument_changes = [
0x03: [0x1BAEC6],
0x04: [0x1BAEE4]}, 0x0B),
InstrumentChange(0x1F, 0x00, {0x00: [0x1BAE9C]}, 0x18),
InstrumentChange(0x1F, 0x00, {0x02: [0x1BAEBC]}, 0x13),
InstrumentChange(0x1F, 0x00, {0x06: [0x1BAF02]}, 0x02),
InstrumentChange(0x1F, 0x00, {0x02: [0x1BAEBC]}, 0x13, type=Am|Be, ban=[0x01, 0x05, 0x0F]),
InstrumentChange(0x1F, 0x00, {0x06: [0x1BAF02]}, 0x02, ban=[0x10]),
InstrumentChange(0x1F, 0x01, {0x03: [0x1BAE15],
0x04: [0x1BAE32],
0x05: [0x1BAE4F]}, 0x11),
@@ -829,7 +829,7 @@ spc_instrument_changes = [
InstrumentChange(0x1F, 0x02, {0x03: [0x1BAF53],
0x04: [0x1BAF69],
0x05: [0x1BAF7F]}, 0x11),
InstrumentChange(0x1F, 0x04, {0x02: [0x1BAFAA]}, 0x13),
InstrumentChange(0x1F, 0x04, {0x02: [0x1BAFAA]}, 0x13, type=Am|Be, ban=[0x01, 0x05, 0x0F]),
InstrumentChange(0x20, 0x00, {0x00: [0x1AD49A],
0x01: [0x1AD4BA],
+1 -1
View File
@@ -148,7 +148,7 @@ SETTINGSTOPROCESS = {
"createrom": "create_rom",
"calcplaythrough": "calc_playthrough",
"print_custom_yaml": "print_custom_yaml",
"saveonexit": "saveonexit"
"settingsonload": "settingsonload"
}
},
"startinventory": {
+710
View File
@@ -0,0 +1,710 @@
UwGeneralDeny:
- [ 0x0002, 0, [ "RollerVerticalDown", "Statue" ] ] #"Sewers - Rat Pots - Rat 1"
- [ 0x0002, 1, [ "RollerVerticalDown", "Statue" ] ] #"Sewers - Rat Pots - Rat 2"
- [ 0x0002, 2, [ "RollerVerticalUp", "Statue" ] ] #"Sewers - Rat Pots - Rat 3"
- [ 0x0002, 3, [ "RollerVerticalUp", "Statue" ] ] #"Sewers - Rat Pots - Rat 4"
- [ 0x0002, 4, [ "Statue" ] ] #"Sewers - Rat Pots - Rat 5"
- [ 0x0002, 15, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Sewers - Rat Pots - Rat 6"
- [ 0x0002, 16, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Sewers - Rat Pots - Rat 7"
- [ 0x0004, 1, ["Statue"]]
- [ 0x0004, 2, ["Statue"]]
- [ 0x0004, 3, ["Statue"]]
- [ 0x0004, 4, ["Statue"]]
- [ 0x0004, 15, ["Statue"]]
- [ 0x000a, 0, [ "RollerVerticalDown", "RollerVerticalUp" ] ] #"Palace of Darkness - Basement Ledge - Terrorpin 1"
- [ 0x000a, 1, [ "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Palace of Darkness - Basement Ledge - Terrorpin 2"
- [ 0x000b, 1, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Callback - Terrorpin 1"
- [ 0x000e, 0, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Ice Palace - Entrance - Freezor"
- [ 0x000e, 1, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Ice Palace - Bari Key - Top Bari"
- [ 0x000e, 2, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Ice Palace - Bari Key - Middle Bari"
- [ 0x0016, 0, [ "RollerVerticalDown", "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Pool - Zol 1"
- [ 0x0016, 1, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Pool - Zol 2"
- [ 0x0016, 2, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Pool - Blue Bari"
- [ 0x0016, 3, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Pool - Zol 3"
- [ 0x0017, 5, [ "Beamos", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Tower Of Hera - Bumper Room - Fire Bar (Clockwise)"
- [ 0x0019, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Dark Maze - Kodongo 1"
- [ 0x0019, 1, [ "RollerVerticalUp" ] ] #"Palace of Darkness - Dark Maze - Kodongo 2"
- [ 0x0019, 2, [ "RollerVerticalDown", "RollerVerticalUp" ] ] #"Palace of Darkness - Dark Maze - Kodongo 3"
- [ 0x0019, 3, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft" ] ] #"Palace of Darkness - Dark Maze - Kodongo 4"
- [ 0x001a, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Compass Room - Mini Helmasaur 1"
- [ 0x001a, 5, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Compass Room - Mini Helmasaur 2"
- [ 0x001b, 3, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Palace of Darkness - Mimics 2 - Red Eyegore"
- [ 0x001b, 4, [ "RollerVerticalUp" ] ] #"Palace of Darkness - Mimics 2 - Green Eyegore L"
- [ 0x001e, 3, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Red Bari 3"
- [ 0x001e, 4, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Red Bari 4"
- [ 0x001e, 5, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Zol 1"
- [ 0x001e, 6, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Blob Ambush - Zol 2"
- [ 0x001f, 0, [ "RollerHorizontalRight" ] ] #"Ice Palace - Big Key View - Pengator 1"
- [ 0x001f, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x0021, 3, [ "RollerVerticalDown", "RollerVerticalUp" ] ] #"Sewers - Dark U - Rat 2"
- [ 0x0021, 4, [ "RollerVerticalDown", "RollerVerticalUp" ] ] #"Sewers - Dark U - Rat 3"
- [ 0x0024, 6, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x0026, 1, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "Statue" ] ] #"Swamp Palace - Big Spoon - Red Bari 1"
- [ 0x0026, 8, [ "AntiFairyCircle", "Bumper", "Statue" ] ] #"Swamp Palace - Big Spoon - Red Bari 3"
- [ 0x0026, 9, [ "RollerHorizontalRight", "Statue" ] ] #"Swamp Palace - Big Spoon - Kyameron"
- [ 0x0026, 10, [ "Statue" ] ] # multiple push statues in this room can cause issues
- [ 0x0026, 11, [ "Statue" ] ] # multiple push statues in this room can cause issues
- [ 0x0027, 0, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalLeft", "FirebarCW" ] ] #"Tower Of Hera - Petting Zoo - Mini Moldorm 1"
- [ 0x0027, 1, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Tower Of Hera - Petting Zoo - Mini Moldorm 2"
- [ 0x0027, 2, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Tower Of Hera - Petting Zoo - Mini Moldorm 3"
- [ 0x0027, 4, ["Bumper", "BigSpike", "AntiFairyCircle", "RollerVerticalDown", "RollerVerticalUp"]]
- [ 0x0027, 5, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Tower Of Hera - Petting Zoo - Kodongo 1"
- [ 0x0028, 4, [ "RollerVerticalUp" ] ] #"Swamp Palace - Entrance Ledge - Spike Trap"
- [ 0x002a, 2, [ "SparkCW", "SparkCCW", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]] #"Palace of Darkness - Arena Main - Hardhat Beetle 1"
- [ 0x002a, 3, [ "Statue", "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Arena Main - Hardhat Beetle 2"
- [ 0x002a, 4, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ]]
- [ 0x002a, 6, [ "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Arena Main - Hardhat Beetle 5"
- [ 0x002b, 5, [ "RollerHorizontalRight" ] ] #"Palace of Darkness - Fairies - Red Bari 2"
- [ 0x002e, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "BigSpike", "FirebarCW", "FirebarCCW" ] ] #"Ice Palace - Penguin Chest - Pengator 1"
- [ 0x002e, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "BigSpike", "FirebarCW", "FirebarCCW" ] ] #"Ice Palace - Penguin Chest - Pengator 2"
- [ 0x002e, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "BigSpike", "FirebarCW", "FirebarCCW" ] ] #"Ice Palace - Penguin Chest - Pengator 3"
- [ 0x002e, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "BigSpike", "FirebarCW", "FirebarCCW" ] ] #"Ice Palace - Penguin Chest - Pengator 4"
- [ 0x002e, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "BigSpike", "FirebarCW", "FirebarCCW" ] ] #"Ice Palace - Penguin Chest - Pengator 5"
- [ 0x002e, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "BigSpike", "FirebarCW", "FirebarCCW" ] ] #"Ice Palace - Penguin Chest - Pengator 6"
- [ 0x0034, 0, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - West Wing - Hover 1"
- [ 0x0034, 1, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - West Wing - Hover 2"
- [ 0x0034, 2, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - West Wing - Kyameron"
- [ 0x0034, 4, [ "Statue", "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - West Wing - Zol"
- [ 0x0035, 6, [ "RollerHorizontalRight" ] ] #"Swamp Palace - West Lever - Stalfos 2"
- [ 0x0035, 9, [ "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Swamp Palace - West Lever - Blue Bari"
- [ 0x0036, 7, [ "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Lobby - Hover 3"
- [ 0x0037, 7, [ "RollerHorizontalRight" ] ] #"Swamp Palace - Water 1 - Blue Bari"
- [ 0x0038, 4, [ "RollerHorizontalRight" ] ] #"Swamp Palace - Long Hall - Kyameron 2"
- [ 0x0039, 3, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Skull Woods - Play Pen - Mini Helmasaur"
- [ 0x0039, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 1"
- [ 0x0039, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft" ] ] #"Skull Woods - Play Pen - Hardhat Beetle"
- [ 0x0039, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 2"
- [ 0x003b, 1, [ "Bumper" ]]
- [ 0x003c, 0, ["BigSpike"]]
- [ 0x003c, 1, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Hookshot Cave - Blue Bari 1"
- [ 0x003c, 2, [ "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Hookshot Cave - Blue Bari 2"
- [ 0x003d, 9, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Spark (Counterclockwise)"
- [ 0x003d, 10, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Spark (Clockwise) 1"
- [ 0x003d, 12, [ "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Bunny Beam"
- [ 0x003d, 13, [ "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Torches 2 - Antifairy"
- [ 0x003f, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper", "Statue"] ] #"Ice Palace - P Room - Stalfos Knight 1"
- [ 0x003f, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper", "Statue"] ] #"Ice Palace - P Room - Stalfos Knight 2"
- [ 0x003f, 4, [ "Wizzrobe", "Statue", "Bumper", "BigSpike", "AntiFairyCircle"]] # Wizzrobes can't spawn on pots
- [ 0x0040, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] # Agahnims Tower - Bridge - Blue Guard 1
- [ 0x0040, 1, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] # Agahnims Tower - Bridge - Blue Guard 2
- [ 0x0041, 0, [ "RollerHorizontalLeft" ] ] #"Sewers - Dark Cactus - Rat 1"
- [ 0x0041, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Sewers - Dark Cactus - Rat 2"
- [ 0x0041, 2, [ "RollerVerticalUp" ] ] #"Sewers - Dark Cactus - Rat 3"
- [ 0x0042, 0, [ "SparkCW", "SparkCCW", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sewers - Dark Rope Corridor - Rope 1"
- [ 0x0042, 1, [ "SparkCW", "SparkCCW", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sewers - Dark Rope Corridor - Rope 2"
- [ 0x0042, 2, [ "SparkCW", "SparkCCW", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sewers - Dark Rope Corridor - Rope 3"
- [ 0x0042, 3, [ "SparkCW", "SparkCCW", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Sewers - Dark Rope Corridor - Rope 4"
- [ 0x0042, 4, [ "SparkCW", "SparkCCW", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Sewers - Dark Rope Corridor - Rope 5"
- [ 0x0042, 5, [ "SparkCW", "SparkCCW", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Sewers - Dark Rope Corridor - Rope 6"
- [ 0x0044, 4, [ "RollerVerticalUp", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Joke Room - Zol"
- [ 0x0044, 6, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "BigSpike" ] ] #"Thieves' Town - Joke Room - Red Bari"
- [ 0x0044, 8, [ "Statue", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Joke Room - Blue Bari 4"
- [ 0x0045, 1, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Thieves' Town - Basement Block Totems - Red Zazak"
- [ 0x0045, 4, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x0045, 7, [ "AntiFairyCircle", "Bumper" ] ] #"Thieves' Town - Cells - Blue Zazak 4"
- [ 0x0045, 8, [ "RollerHorizontalRight" ] ] #"Thieves' Town - Cells - Zol"
- [ 0x0046, 0, [ "RollerVerticalUp", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper", "Statue" ] ] #"Swamp Palace - Big O Top - Hover 1"
- [ 0x0046, 2, [ "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper", "Statue" ] ] #"Swamp Palace - Big O Top - Hover 2"
- [ 0x0046, 4, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper", "Statue" ] ] #"Swamp Palace - Big O Top - Hover 3"
- [ 0x0049, 5, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Skull Woods - Bari Pits - Gibdo 2"
- [ 0x0049, 7, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Skull Woods - Bari Pits - Gibdo 4"
- [ 0x0049, 8, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Skull Woods - Bari Pits - Gibdo 5"
- [ 0x004b, 0, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Palace of Darkness - Mimics 1 - Red Eyegore"
- [ 0x004b, 1, [ "RollerHorizontalRight" ] ] #"Palace of Darkness - Warp Hint - Antifairy 1"
- [ 0x004b, 5, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 1"
- [ 0x004b, 6, [ "AntiFairyCircle", "BigSpike" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 2"
- [ 0x004b, 7, [ "AntiFairyCircle", "BigSpike" ] ] #"Palace of Darkness - Jelly Hall - Blue Bari 3"
- [ 0x004e, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 1"
- [ 0x004e, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 2"
- [ 0x004e, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Blob Alley - Zol 3"
- [ 0x0050, 0, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Guard"
- [ 0x0050, 1, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Knife Guard 1"
- [ 0x0050, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Hyrule Castle - North West Passage - Green Knife Guard 2"
- [ 0x0052, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper" ] ] #"Hyrule Castle - North East Passage - Green Guard"
- [ 0x0052, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper" ] ] #"Hyrule Castle - North East Passage - Green Knife Guard 1"
- [ 0x0052, 2, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "Bumper" ] ] #"Hyrule Castle - North East Passage - Green Knife Guard 2"
- [ 0x0053, 1, [ "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - Bridge - Beamos 1"
- [ 0x0053, 5, [ "RollerVerticalDown" ] ] #"Desert Palace - Popo Genocide - Popo TL"
- [ 0x0053, 7, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - Bridge - Popo 5"
- [ 0x0055, 1, [ "RollerVerticalUp", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Secret Passage Exit - Green Knife Guard 1"
- [ 0x0057, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x0057, 1, ["Statue"]] # Statue switch issues
- [ 0x0057, 2, [ "RollerVerticalUp", "AntiFairyCircle", "Bumper", "Statue" ] ] #"Skull Woods - Big Key Room - Spike Trap"
- [ 0x0057, 3, ["Statue"]] # Statue switch issues
- [ 0x0057, 4, ["Statue"]] # Statue switch issues
- [ 0x0057, 5, ["Statue"]] # Statue switch issues
- [ 0x0057, 7, [ "RollerVerticalUp", "RollerVerticalDown", "Statue" ] ] #"Skull Woods - Big Key Room - Gibdo 2"
- [ 0x0057, 8, ["Statue"]] # Statue switch issues
- [ 0x0057, 9, ["Statue"]] # Statue switch issues
- [ 0x0057, 10, ["Statue"]] # Statue switch issues
- [ 0x0057, 11, ["Statue"]] # Statue switch issues
- [ 0x0057, 12, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper", "BigSpike", "SpikeBlock", "Statue"]] #"Skull Woods - Big Key Room - Gibdo 6"
- [ 0x0057, 13, [ "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper", "Statue" ] ] #"Skull Woods - Big Key Room - Blue Bari 1"
- [ 0x0057, 14, [ "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper", "Statue" ] ] #"Skull Woods - Big Key Room - Blue Bari 2"
- [ 0x0058, 0, ["Statue"]]
- [ 0x0058, 1, ["Statue"]]
- [ 0x0058, 2, ["Statue"]]
- [ 0x0058, 3, ["Statue"]]
- [ 0x0058, 4, ["Statue"]]
- [ 0x0058, 6, ["Statue"]]
- [ 0x0058, 7, [ "RollerHorizontalLeft", "Statue" ] ] #"Skull Woods - Lever Room - Hardhat Beetle 2"
- [ 0x0058, 8, ["Statue"]]
- [ 0x0059, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Mini Moldorm 1"
- [ 0x0059, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Mini Moldorm 2"
- [ 0x0059, 9, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Skull Woods - Bridge Room - Gibdo 1"
- [ 0x005e, 3, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Pit Trap - Big Spike Trap"
- [ 0x005e, 4, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Ice Palace - Pit Trap - Fire Bar (Clockwise)"
- [ 0x005f, 0, [ "RollerVerticalDown", "RollerHorizontalLeft" ] ] #"Ice Palace - Bari University - Blue Bari 1"
- [ 0x005f, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Ice Palace - Bari University - Blue Bari 2"
- [ 0x0060, 0, [ "RollerVerticalUp", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Hyrule Castle - West - Blue Guard"
- [ 0x0062, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Hyrule Castle - East - Blue Guard"
- [ 0x0064, 2, [ "Bumper" , "Beamos" ] ] #"Thieves' Town - Attic Hall Left - Keese 2"
- [ 0x0064, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x0064, 4, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Hall Left - Rat 1"
- [ 0x0065, 0, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Attic Window - Rat 1"
- [ 0x0065, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Window - Rat 2"
- [ 0x0065, 2, [ "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Thieves' Town - Attic Window - Rat 3"
- [ 0x0066, 0, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Swamp Palace - Waterfall Room - Hover 1"
- [ 0x0066, 2, [ "AntiFairyCircle", "Bumper"]]
- [ 0x0067, 1, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Blue Bari 1"
- [ 0x0067, 2, ["Bumper"]] #"Skull Woods - Firebar Pits - Blue Bari 2"
- [ 0x0067, 3, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 1"
- [ 0x0067, 4, [ "AntiFairyCircle", "Bumper" ]]
- [ 0x0067, 5, [ "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 3"
- [ 0x0067, 6, [ "RollerVerticalDown" ] ] #"Skull Woods - Firebar Pits - Hardhat Beetle 4"
- [ 0x0067, 7, [ "Beamos", "AntiFairyCircle", "Bumper", "BunnyBeam" ] ] #"Skull Woods - Firebar Pits - Fire Bar (Clockwise)"
- [ 0x006a, 0, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Dark Alley - Terrorpin 1"
- [ 0x006a, 1, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Dark Alley - Terrorpin 2"
- [ 0x006a, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Palace of Darkness - Dark Alley - Antifairy 1"
- [ 0x006a, 4, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Dark Alley - Terrorpin 3"
- [ 0x006a, 5, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Palace of Darkness - Dark Alley - Terrorpin 4"
- [ 0x006b, 7, [ "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Mimics 1 - Spike Trap 1"
- [ 0x0071, 0, [ "RollerHorizontalLeft" ] ] #"Hyrule Castle - Basement Trap - Green Guard"
- [ 0x0074, 0, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - North Hallway - Red Devalant 1"
- [ 0x0074, 1, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - North Hallway - Red Devalant 2"
- [ 0x0074, 4, [ "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - North Hallway - Leever 1"
- [ 0x0074, 5, [ "AntiFairyCircle", "Bumper" ] ] #"Desert Palace - North Hallway - Leever 2"
- [ 0x0076, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Hover 1"
- [ 0x0076, 2, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Kyameron"
- [ 0x0076, 3, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Hover 2"
- [ 0x0076, 4, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Swamp Palace - Toilet Left - Zol"
- [ 0x0076, 6, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Swamp Palace - Toilet Left - Blue Bari"
- [ 0x007b, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - DMs Room - Blue Bari 1"
- [ 0x007b, 1, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - DMs Room - Blue Bari 2"
- [ 0x007b, 6, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - DMs Room - Statue"
- [ 0x007b, 7, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - DMs Room - Hardhat Beetle"
- [ 0x007c, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Randomizer Room - Fire Bar (Counterclockwise)"
- [ 0x007c, 2, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Randomizer Room - Spike Trap"
- [ 0x007c, 3, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Randomizer Room - Fire Bar (Clockwise)"
- [ 0x007c, 4, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Randomizer Room - Hardhat Beetle"
- [ 0x007d, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - The Zoo - Fire Snake 1"
- [ 0x007d, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - The Zoo - Fire Snake 2"
- [ 0x007d, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - The Zoo - Fire Snake 3"
- [ 0x007d, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - The Zoo - Fire Snake 4"
- [ 0x007d, 4, ["StalfosKnight", "Geldman", "Blob", "Stal"]]
- [ 0x007d, 7, ["RollerVerticalUp", "RollerHorizontalLeft", "StalfosKnight", "Geldman", "Blob", "Stal"]] #"Ganon's Tower - The Zoo - Mini Helmasaur"
- [ 0x007d, 8, ["RollerVerticalUp", "RollerHorizontalLeft", "RollerHorizontalRight", "StalfosKnight", "Geldman", "Blob", "Stal"]] #"Ganon's Tower - The Zoo - Red Bari"
- [ 0x007d, 10, ["StalfosKnight", "Geldman", "Blob", "Stal"]]
# todo - consider adding firesnake to 0-3: has a hard time moving, could block hookshots for quite a while
- [ 0x007f, 0, [ "Statue", "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Big Spikes - Red Bari 1"
- [ 0x007f, 1, [ "Statue", "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper", "ArmosStatue" ] ] #"Ice Palace - Big Spikes - Red Bari 2"
- [ 0x007f, 2, [ "Statue", "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Big Spikes - Red Bari 3"
- [ 0x007f, 3, [ "Statue", "SparkCW", "SparkCCW", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Big Spikes - Red Bari 4"
- [ 0x007f, 4, [ "RollerVerticalDown" ] ] #"Ice Palace - Big Spikes - Big Spike Trap 1"
- [ 0x007f, 5, [ "RollerVerticalDown" ] ] #"Ice Palace - Big Spikes - Big Spike Trap 2"
- [ 0x0082, 0, [ "RollerVerticalDown" ] ] #"Hyrule Castle - Basement Playpit - Blue Guard 1"
- [ 0x0082, 2, [ "RollerVerticalUp" ] ] #"Hyrule Castle - Basement Playpit - Blue Guard 3"
- [ 0x0083, 0, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Desert Palace - Left Hallway - Blue Devalant 1"
- [ 0x0084, 0, [ "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Main Room - Left - Leever 1"
- [ 0x0084, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Main Room - Left - Leever 2"
- [ 0x0085, 2, [ "RollerHorizontalRight" ] ] #"Desert Palace - Compass Room - Popo TL"
- [ 0x0085, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Desert Palace - Right Hallway - Leever 2"
- [ 0x008b, 3, ["RollerHorizontalRight"]]
- [ 0x008b, 4, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper", "BigSpike"]] #"Ganon's Tower - Map Room - Spike Trap"
- [ 0x008b, 6, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Map Room - Fire Bar (Clockwise)"
- [ 0x008b, 7, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Map Room - Fire Bar (Counterclockwise)"
- [ 0x008c, 14, ["AntiFairyCircle", "BigSpike", "Bumper"]]
- [ 0x008d, 1, [ "AntiFairyCircle", "Bumper" ] ] #"Ganon's Tower - Tile Room - Yomo Medusa T"
- [ 0x008d, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Tile Room - Spike Trap"
- [ 0x008d, 8, [ "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Tile Room - Stalfos"
- [ 0x008d, 9, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Tile Room - Fire Bar (Clockwise)"
- [ 0x008d, 10, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Ganon's Tower - Tile Room - Blue Bari 1"
- [ 0x008d, 12, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Ganon's Tower - Tile Room - Blue Bari 2"
- [ 0x008e, 2, [ "Wizzrobe", "Statue"] ] # Wizzrobes can't spawn on pots
- [ 0x0092, 8, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Misery Mire - Dark Weave - Spike Trap"
- [ 0x0092, 9, [ "RollerHorizontalRight" ] ] #"Misery Mire - Dark Weave - Antifairy 3"
- [ 0x0092, 10, [ "RollerHorizontalLeft" ] ] #"Misery Mire - Dark Weave - Stalfos"
- [ 0x0095, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 1"
- [ 0x0095, 1, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 2"
- [ 0x0095, 2, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 3"
- [ 0x0095, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock" ] ] #"Ganon's Tower - Conveyer Falling Bridge - Red Spear Guard 4"
- [ 0x0096, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Torches 1 - Fire Bar (Clockwise)"
- [ 0x0098, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 1"
- [ 0x0098, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 2"
- [ 0x0098, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 3"
- [ 0x0098, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 4"
- [ 0x0098, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Entrance - Zol 5"
- [ 0x009b, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Spike Switch - Spike Trap 1"
- [ 0x009b, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Spike Switch - Spike Trap 2"
- [ 0x009b, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ]
- [ 0x009b, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Spike Switch - Spike Trap 4"
- [ 0x009b, 8, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Spike Switch - Spike Trap 5"
- [ 0x009b, 9, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Spike Switch - Spike Trap 6"
- [ 0x009b, 10, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Spike Switch - Spike Trap 7"
- [ 0x009c, 1, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Mini Helmasaur"
- [ 0x009c, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 2"
- [ 0x009c, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 3"
- [ 0x009c, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 4"
- [ 0x009c, 5, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Invisible Floor Maze - Hardhat Beetle 5"
- [ 0x009d, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ganon's Tower - Compass Room - Gibdo 2"
- [ 0x009d, 6, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Ganon's Tower - Compass Room - Blue Bari 1"
- [ 0x009d, 7, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Compass Room - Blue Bari 2"
- [ 0x009d, 8, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Ganon's Tower - Compass Room - Blue Bari 3"
- [ 0x009e, 0, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Fairy Drop - blue - Red Bari 1"
- [ 0x009e, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Fairy Drop - blue - Red Bari 2"
- [ 0x009e, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Fairy Drop - blue - Stalfos Knight"
- [ 0x009e, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Fairy Drop - blue - Red Bari 3"
- [ 0x00a0, 1, [ "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Boss Antechamber - Antifairy"
- [ 0x00a1, 2, [ "Statue", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Fish Room - Spark (Clockwise) 2"
- [ 0x00a1, 7, [ "Wizzrobe", "Statue"] ] # Wizzrobes can't spawn on pots
- [ 0x00a5, 2, [ "BigSpike" ] ] #"GT Wizzrobes 1 - Wizzrobe 3"
- [ 0x00a5, 10, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Laser Bridge - Red Spear Guard"
- [ 0x00a8, 1, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Eastern Palace - West Wing - Top - Stalfos 2"
- [ 0x00a8, 3, [ "RollerVerticalDown", "RollerHorizontalLeft" ] ] #"Eastern Palace - West Wing - Top - Stalfos 4"
- [ 0x00a9, 1, [ "RollerHorizontalRight", "RollerHorizontalLeft" ] ]
- [ 0x00aa, 4, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - East Wing - Top - Stalfos 3"
- [ 0x00aa, 5, [ "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - East Wing - Top - Popo B 2"
- [ 0x00ab, 7, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Thieves' Town - Spike Dodge - Spike Trap 6"
- [ 0x00ae, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Ice T - Blue Bari 1"
- [ 0x00ae, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ice Palace - Ice T - Blue Bari 2"
- [ 0x00af, 0, [ "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Ice Clock - Fire Bar (Clockwise)"
- [ 0x00b1, 2, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Misery Mire - Hourglass - Spike Trap 1"
- [ 0x00b1, 3, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Misery Mire - Hourglass - Spike Trap 2"
- [ 0x00b1, 4, ["Bumper", "BigSpike", "AntiFairyCircle" ]]
- [ 0x00b2, 1, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x00b2, 3, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x00b2, 6, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Misery Mire - Sluggula Cross - Sluggula TR"
- [ 0x00b2, 8, [ "RollerVerticalDown" ] ] #"Misery Mire - Popo Push - Medusa 1"
- [ 0x00b2, 9, [ "RollerVerticalUp" ] ] #"Misery Mire - Sluggula Cross - Sluggula BL"
- [ 0x00b3, 0, [ "RollerVerticalUp", "RollerHorizontalRight", "BigSpike", "SpikeBlock" ] ] #"Misery Mire - Spike Room - Stalfos 1"
- [ 0x00b3, 2, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "Bumper" ] ] #"Misery Mire - Spike Room - Beamos"
- [ 0x00b3, 3, [ "AntiFairyCircle", "Bumper" ] ] #"Misery Mire - Spike Room - Yomo Medusa"
- [ 0x00b6, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Tile Room - Zol 1"
- [ 0x00b6, 8, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Tile Room - Zol 2"
- [ 0x00ba, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Dark Stalfos - Antifairy 1"
- [ 0x00ba, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Dark Stalfos - Antifairy 2"
- [ 0x00ba, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Dark Stalfos - Popo B 1"
- [ 0x00ba, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Dark Stalfos - Popo B 2"
- [ 0x00bb, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Spikeveyer - Gibo 1"
- [ 0x00bb, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "Bumper" ] ] #"Thieves' Town - Spikeveyer - Antifairy 1"
- [ 0x00bb, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Spikeveyer - Gibo 3"
- [ 0x00bb, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Spikeveyer - Fire Snake"
- [ 0x00bb, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Spikeveyer - Gibo 4"
- [ 0x00bb, 8, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Spikeveyer - Gibo 5"
- [ 0x00bb, 9, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Spikeveyer - Antifairy 2"
- [ 0x00bc, 6, [ "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Toilet - Stalfos 2"
- [ 0x00bc, 7, [ "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Toilet - Stalfos 3"
- [ 0x00bc, 8, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Thieves' Town - Toilet - Stalfos 4"
- [ 0x00bf, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on collision
- [ 0x00c1, 3, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Misery Mire - 4 Rails - Stalfos 1"
- [ 0x00c2, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Misery Mire - Main Lobby - blue - Fire Snake 1"
- [ 0x00c2, 5, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x00c5, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Catwalk - Mini Helmasaur"
- [ 0x00c5, 7, [ "Statue" ] ] #"Turtle Rock - Catwalk - Laser Eye (Left) 4"
- [ 0x00cb, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x00cb, 3, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 1"
- [ 0x00cb, 5, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 2"
- [ 0x00cb, 9, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ]
- [ 0x00cb, 10, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ]
- [ 0x00cb, 11, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x00cc, 8, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #Prevents Pot access (Beamos okay?)
- [ 0x00cc, 12, [ "RollerVerticalUp", "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #Prevents Pot access (Beamos okay?)
- [ 0x00ce, 0, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "Antifairy", "BigSpike", "FirebarCCW", "Bumper" ] ] #"Ice Palace - Over Boss - top - Red Bari 1"
- [ 0x00ce, 1, [ "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "AntiFairyCircle", "Antifairy", "BigSpike", "FirebarCW", "Bumper" ] ] #"Ice Palace - Over Boss - top - Red Bari 2"
- [ 0x00ce, 3, [ "SparkCW", "SparkCCW", "RollerVerticalDown", "RollerVerticalUp", "RollerHorizontalRight", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "Antifairy", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Over Boss - top - Statue"
- [ 0x00ce, 4, [ "RollerVerticalDown", "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Beamos", "Bumper", "FirebarCW", "FirebarCCW"]]
- [ 0x00ce, 5, [ "RollerVerticalDown", "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Beamos", "Bumper", "FirebarCW", "FirebarCCW"]]
- [ 0x00ce, 6, [ "RollerVerticalDown", "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Beamos", "Bumper", "FirebarCW", "FirebarCCW"]]
- [ 0x00ce, 7, [ "RollerVerticalDown", "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Beamos", "Bumper", "FirebarCW", "FirebarCCW"]]
- [ 0x00d0, 0, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
- [ 0x00d0, 1, [ "AntiFairyCircle", "BigSpike", "Bumper"]]
- [ 0x00d0, 4, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
- [ 0x00d0, 5, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
- [ 0x00d0, 6, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
- [ 0x00d0, 7, [ "Statue", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper"]]
- [ 0x00d0, 9, [ "AntiFairyCircle", "BigSpike", "Bumper"]]
- [ 0x00d0, 6, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] # Agahnims Tower - Dark Maze - Blue Guard 2
- [ 0x00d2, 8, [ "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Mire 2 - Popo BL"
- [ 0x00d5, 4, [ "Statue", "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "FirebarCW", "FirebarCCW", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Eye Bridge - Hardhat Beetle"
- [ 0x00d8, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Red Eyegore L"
- [ 0x00d8, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Red Eyegore R"
- [ 0x00d8, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Popo B TL"
- [ 0x00d8, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Popo B TR"
- [ 0x00d8, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Popo B LT"
- [ 0x00d8, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Popo B RT"
- [ 0x00d8, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Popo LB"
- [ 0x00d8, 7, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Eastern Palace - Kill Room 2 - Popo RB"
- [ 0x00d8, 8, [ "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Eastern Palace - Kill Room 1 - Red Eyegore"
- [ 0x00d9, 1, [ "RollerHorizontalRight" ] ] #"Eastern Palace - Dodgeball - Green Eyegore 1"
- [ 0x00db, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots
- [ 0x00dc, 2, [ "AntiFairyCircle", "BigSpike", "Bumper" ] ]
- [ 0x00dc, 9, [ "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Thieves' Town - Grand Room SE - Fire Snake 2"
- [ 0x00df, 0, [ "RollerVerticalDown", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Paradox Cave - Top - Mini Moldorm 1"
- [ 0x00df, 1, [ "RollerVerticalDown", "RollerHorizontalRight", "AntiFairyCircle" ] ] #"Paradox Cave - Top - Mini Moldorm 2"
- [ 0x00e4, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 1"
- [ 0x00e4, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 2"
- [ 0x00e4, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 3"
- [ 0x00e5, 4, [ "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home Circle - Keese 5"
- [ 0x00e5, 5, [ "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home Circle - Keese 6"
- [ 0x00e7, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Death Mountain Descent Cave Right - Keese 1"
- [ 0x00e7, 1, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Death Mountain Descent Cave Right - Keese 2"
- [ 0x00e7, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Death Mountain Descent Cave Right - Keese 3"
- [ 0x00e7, 3, [ "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Death Mountain Descent Cave Right - Keese 4"
- [ 0x00e7, 4, [ "RollerVerticalDown", "Beamos", "AntiFairyCircle", "Bumper" ] ] #"Death Mountain Descent Cave Right - Keese 5"
- [ 0x00e7, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Death Mountain Descent Cave Right - Keese 6"
- [ 0x00e7, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Death Mountain Descent Cave Right - Keese 7"
- [ 0x00e8, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "SpikeBlock", "Bumper" ] ] #"Super Bunny Exit - Hardhat Beetle 1"
- [ 0x00e8, 1, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Super Bunny Exit - Hardhat Beetle 2"
- [ 0x00ee, 0, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Sprial Cave Top - Mini Moldorm 1"
- [ 0x00ee, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sprial Cave Top - Mini Moldorm 2"
- [ 0x00ee, 2, [ "RollerHorizontalLeft", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sprial Cave Top - Mini Moldorm 3"
- [ 0x00ee, 3, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sprial Cave Top - Blue Bari 1"
- [ 0x00ee, 4, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Sprial Cave Top - Blue Bari 2"
- [ 0x00ef, 1, [ "RollerVerticalUp", "RollerVerticalDown" ] ] #"Paradox Cave - Middle - Mini Moldorm 2"
- [ 0x00f1, 0, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 1"
- [ 0x00f1, 1, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 2"
- [ 0x00f1, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 3"
- [ 0x00f1, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 4"
- [ 0x00f1, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 5"
- [ 0x00f1, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 6"
- [ 0x00fd, 0, [ "Bumper" ] ]
- [ 0x0107, 1, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]]
- [ 0x0107, 2, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]]
- [0x010b, 6, ["RollerHorizontalRight"]]
- [0x010c, 6, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
- [0x010c, 7, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
OwGeneralDeny:
- [0x03, 2, ["Gibo"]] # OldMan eating Gibo
- [0x03, 4, ["Gibo"]] # OldMan eating Gibo
- [0x03, 5, ["Gibo"]] # OldMan eating Gibo
- [0x03, 6, ["Gibo"]] # OldMan eating Gibo
- [0x03, 8, ["Gibo"]] # OldMan eating Gibo
- [0x03, 9, ["Gibo"]] # OldMan eating Gibo
- [0x03, 10, ["Gibo"]] # OldMan eating Gibo
- [0x05, 11, ["Bumper", "AntiFairyCircle"]] # Blocks path to portal
- [0x1e, 3, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] # forbid a beamos here
- [0x40, 0, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]]
- [0x40, 7, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]]
- [0x40, 13, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]]
- [0x40, 14, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]]
- [0x5e, 0, ["Gibo"]] # kiki eating Gibo
- [0x5e, 1, ["Gibo"]] # kiki eating Gibo
- [0x5e, 2, ["Gibo"]] # kiki eating Gibo
- [0x5e, 3, ["Gibo"]] # kiki eating Gibo
- [0x5e, 4, ["RollerVerticalUp", "Gibo"]] # forbid that one roller for kiki pod, and the kiki eating Gibo
- [0x5e, 5, ["Gibo"]] # kiki eating Gibo
- [0x5e, 6, ["Gibo"]] # kiki eating Gibo
- [0x5e, 7, ["Gibo"]] # kiki eating Gibo
- [0x5e, 8, ["Gibo"]] # kiki eating Gibo
- [0x5e, 9, ["Gibo"]] # kiki eating Gibo
- [0x5e, 10, ["Gibo"]] # kiki eating Gibo
- [0x5e, 11, ["Gibo"]] # kiki eating Gibo
- [0x5e, 12, ["Gibo"]] # kiki eating Gibo
- [0x5e, 13, ["Gibo"]] # kiki eating Gibo
- [0x5e, 14, ["Gibo"]] # kiki eating Gibo
- [0x5e, 15, ["Gibo"]] # kiki eating Gibo
- [0x5e, 16, ["Gibo"]] # kiki eating Gibo
- [0x5e, 17, ["Gibo"]] # kiki eating Gibo
- [0x5e, 18, ["Gibo"]] # kiki eating Gibo
- [0x5e, 19, ["Gibo"]] # kiki eating Gibo
- [0x5e, 20, ["Gibo"]] # kiki eating Gibo
- [0x77, 1, ["Bumper"]] # soft-lock potential near ladder
UwEnemyDrop:
- [0x0085, 9, ["Babasu"]] # ran off the edge and didn't return
- [0x00cb, 3, ["Zoro"]] # layer issues
- [0x00cb, 5, ["Zoro"]] # layer issues
- [0x00cb, 9, ["Zoro"]] # layer issues
- [0x00cb, 10, ["Zoro"]] # layer issues
- [0x00cc, 5, ["Babasu"]] # little hard to see and kill appropriately
# the following are behind rails or otherwise unactivate-able
- [0x0077, 4, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]] # can't activate here
- [0x0077, 5, ["StalfosKnight", "Geldman", "Blob", "Stal", "Wizzrobe"]]
- [0x008D, 10, ["StalfosKnight", "Geldman", "Blob", "Stal"]]
- [0x008D, 12, ["StalfosKnight", "Geldman", "Blob", "Stal"]]
- [0x00b0, 7, ["StalfosKnight", "Blob", "Stal", "Wizzrobe"]] # blocked, but Geldmen are probably okay
- [0x00b0, 8, ["StalfosKnight", "Blob", "Stal", "Wizzrobe"]] # blocked, but Geldmen are probably okay
# the following are not allowed at certain pits (or on conveyors near pits)
# because they despawned or clipped away or immediately fell, etc
- [0x003d, 9, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x003d, 10, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x0044, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 3, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 4, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0044, 8, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0049, 10, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x007b, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x007b, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x007f, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x007f, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x007f, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x007f, 3, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x0095, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x0095, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x0095, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x0095, 3, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic"]]
- [0x00b5, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00b5, 1, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00b5, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00c6, 2, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00c6, 3, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00c6, 4, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00c6, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Bumper", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00c6, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
- [0x00e6, 0, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard", "Stal", "GreenMimic", "RedMimic", "StalfosKnight", "Geldman", "Blob"]]
# wizzrobe despawn issues - on pots/blocks - too close to some object
- [0x0013, 3, ["Wizzrobe"]]
- [0x0016, 0, ["Wizzrobe"]]
- [0x0016, 1, ["Wizzrobe"]]
- [0x0016, 2, ["Wizzrobe"]]
- [0x0016, 3, ["Wizzrobe"]]
- [0x0017, 5, ["Wizzrobe", "Stal"]]
- [0x0019, 2, ["Wizzrobe"]]
- [0x0019, 3, ["Wizzrobe"]]
- [0x001e, 1, ["Wizzrobe"]]
- [0x001e, 2, ["Wizzrobe"]]
- [0x0027, 5, ["Wizzrobe"]]
- [0x0027, 6, ["Wizzrobe"]]
- [0x002a, 3, ["Wizzrobe"]]
- [0x002a, 7, ["Wizzrobe"]]
- [0x002e, 4, ["Wizzrobe"]]
- [0x0035, 5, ["Wizzrobe"]]
- [0x0036, 8, ["Wizzrobe"]]
- [0x003b, 0, ["Wizzrobe"]]
- [0x003b, 2, ["Wizzrobe"]]
- [0x003b, 4, ["Wizzrobe"]]
- [0x003b, 6, ["Wizzrobe"]]
- [0x003c, 1, ["Wizzrobe"]]
- [0x003d, 11, ["Wizzrobe"]]
- [0x003d, 12, ["Wizzrobe"]]
- [0x003d, 13, ["Wizzrobe"]]
- [0x004b, 2, ["Wizzrobe"]]
- [0x004b, 6, ["Wizzrobe"]]
- [0x004b, 7, ["Wizzrobe"]]
- [0x004e, 3, ["Wizzrobe", "Stal"]]
- [0x0054, 3, ["Wizzrobe", "Stal"]]
- [0x0055, 2, ["Wizzrobe"]] # slightly on wall
- [0x005e, 4, ["Wizzrobe", "Stal"]]
- [0x0065, 3, ["Wizzrobe"]]
- [0x0067, 5, ["Wizzrobe"]]
- [0x0067, 6, ["Wizzrobe"]]
- [0x0067, 7, ["Wizzrobe", "Stal"]]
- [0x0067, 8, ["Wizzrobe", "Stal"]]
- [0x0074, 5, ["Wizzrobe"]]
- [0x007c, 1, ["Wizzrobe", "Stal"]]
- [0x007c, 3, ["Wizzrobe", "Stal"]]
- [0x007e, 1, ["Wizzrobe", "Stal"]]
- [0x007e, 6, ["Wizzrobe", "Stal"]]
- [0x0083, 9, ["Wizzrobe"]]
- [0x008b, 6, ["Wizzrobe", "Stal"]]
- [0x008b, 7, ["Wizzrobe", "Stal"]]
- [0x008d, 9, ["Wizzrobe", "Stal"]]
- [0x0096, 0, ["Wizzrobe", "Stal"]]
- [0x009b, 11, ["Wizzrobe"]]
- [0x009f, 5, ["Wizzrobe", "Stal"]]
- [0x00a1, 1, ["Wizzrobe"]]
- [0x00aa, 5, ["Wizzrobe"]]
- [0x00af, 0, ["Wizzrobe", "Stal"]]
- [0x00b0, 1, ["Wizzrobe"]]
- [0x00b0, 2, ["Wizzrobe"]]
- [0x00b2, 4, ["Wizzrobe"]]
- [0x00b8, 2, ["Wizzrobe"]]
- [0x00bf, 1, ["Wizzrobe"]]
- [0x00c1, 3, ["Wizzrobe", "Stal"]]
- [0x00c2, 0, ["Wizzrobe"]]
- [0x00c2, 3, ["Wizzrobe"]]
- [0x00c2, 7, ["Wizzrobe"]]
- [0x00ce, 4, ["Wizzrobe", "Leever", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt",
"BlueArcher", "RedJavelinGuard", "GreenKnifeGuard", "GreenMimic", "RedMimic"]]
- [0x00ce, 5, ["Wizzrobe", "Leever", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt",
"BlueArcher", "RedJavelinGuard", "GreenKnifeGuard", "GreenMimic", "RedMimic"]]
- [0x00ce, 6, ["Wizzrobe", "Leever", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt",
"BlueArcher", "RedJavelinGuard", "GreenKnifeGuard", "GreenMimic", "RedMimic"]]
- [0x00ce, 7, ["Wizzrobe", "Leever", "BlueGuard", "GreenGuard", "RedSpearGuard", "BluesainBolt", "UsainBolt",
"BlueArcher", "RedJavelinGuard", "GreenKnifeGuard", "GreenMimic", "RedMimic"]]
- [0x00d0, 0, ["Wizzrobe"]]
- [0x00d0, 2, ["Wizzrobe"]]
- [0x00d0, 4, ["Wizzrobe"]]
- [0x00d0, 5, ["Wizzrobe"]]
- [0x00d0, 9, ["Wizzrobe"]]
- [0x00d5, 4, ["Wizzrobe"]]
- [0x00df, 1, ["Wizzrobe"]] # slightly on wall
- [0x00e7, 4, ["Wizzrobe"]] # slightly on wall
- [0x00fd, 1, ["Wizzrobe"]] # slightly on rock
- [0x010c, 4, ["Wizzrobe"]]
- [0x010c, 5, ["Wizzrobe"]]
# other mimic cave spots are in the rail section
# enemies that have problems with conveyors
- [0x003b, 0, ["GreenMimic", "RedMimic"]]
- [0x003b, 1, ["GreenMimic", "RedMimic"]]
- [0x003b, 2, ["GreenMimic", "RedMimic"]]
- [0x003b, 3, ["GreenMimic", "RedMimic"]]
- [0x003b, 4, ["GreenMimic", "RedMimic"]]
- [0x003b, 5, ["GreenMimic", "RedMimic"]]
- [0x003b, 6, ["GreenMimic", "RedMimic"]]
- [0x003d, 6, ["GreenMimic", "RedMimic"]]
- [0x003d, 7, ["GreenMimic", "RedMimic"]]
- [0x003e, 8, ["GreenMimic", "RedMimic"]]
- [0x003e, 9, ["GreenMimic", "RedMimic"]]
- [0x003e, 10, ["GreenMimic", "RedMimic"]]
- [0x003e, 11, ["GreenMimic", "RedMimic"]]
- [0x0044, 0, ["GreenMimic", "RedMimic"]]
- [0x0044, 1, ["GreenMimic", "RedMimic"]]
- [0x0044, 2, ["GreenMimic", "RedMimic"]]
- [0x0044, 3, ["GreenMimic", "RedMimic"]]
- [0x0044, 5, ["GreenMimic", "RedMimic"]]
- [0x004c, 0, ["GreenMimic", "RedMimic"]]
- [0x004c, 1, ["GreenMimic", "RedMimic"]]
- [0x004c, 2, ["GreenMimic", "RedMimic"]]
- [0x004c, 3, ["GreenMimic", "RedMimic"]]
- [0x004c, 4, ["GreenMimic", "RedMimic"]]
- [0x004c, 5, ["GreenMimic", "RedMimic"]]
- [0x004c, 6, ["GreenMimic", "RedMimic"]]
- [0x004c, 7, ["GreenMimic", "RedMimic"]]
- [0x005d, 3, ["GreenMimic", "RedMimic"]]
- [0x005d, 4, ["GreenMimic", "RedMimic"]]
- [0x005d, 5, ["GreenMimic", "RedMimic"]]
- [0x005d, 6, ["GreenMimic", "RedMimic"]]
- [0x005d, 8, ["GreenMimic", "RedMimic"]]
- [0x005d, 9, ["GreenMimic", "RedMimic"]]
- [0x005d, 10, ["GreenMimic", "RedMimic"]]
- [0x005d, 11, ["GreenMimic", "RedMimic"]]
- [0x005d, 12, ["GreenMimic", "RedMimic"]]
# - [0x006d, ?, ["GreenMimic", "RedMimic"]] # conveyor doesn't hit edge
# - [0x008b, ?, ["GreenMimic", "RedMimic"]] # conveyor doesn't hit edge
- [0x0092, 2, ["GreenMimic", "RedMimic"]]
- [0x00a5, 0, ["GreenMimic", "RedMimic"]]
- [0x00a5, 1, ["GreenMimic", "RedMimic"]]
- [0x00a5, 4, ["GreenMimic", "RedMimic"]]
- [0x00a5, 5, ["GreenMimic", "RedMimic"]]
- [0x00a5, 6, ["GreenMimic", "RedMimic"]]
- [0x00bb, 1, ["GreenMimic", "RedMimic"]]
- [0x00bb, 4, ["GreenMimic", "RedMimic"]]
- [0x00bb, 5, ["GreenMimic", "RedMimic"]]
- [0x00bb, 6, ["GreenMimic", "RedMimic"]]
- [0x00bb, 7, ["GreenMimic", "RedMimic"]]
- [0x00bb, 8, ["GreenMimic", "RedMimic"]]
- [0x00bb, 9, ["GreenMimic", "RedMimic"]]
- [0x00bb, 10, ["GreenMimic", "RedMimic"]]
- [0x00bc, 0, ["GreenMimic", "RedMimic"]]
- [0x00bc, 1, ["GreenMimic", "RedMimic"]]
- [0x00bc, 2, ["GreenMimic", "RedMimic"]]
- [0x00bc, 3, ["GreenMimic", "RedMimic"]]
- [0x00bc, 4, ["GreenMimic", "RedMimic"]]
- [0x00bc, 5, ["GreenMimic", "RedMimic"]]
- [0x00c1, 5, ["GreenMimic", "RedMimic"]]
- [0x00c1, 8, ["GreenMimic", "RedMimic"]]
- [0x00c1, 9, ["GreenMimic", "RedMimic"]]
- [0x00c1, 10, ["GreenMimic", "RedMimic"]]
- [0x00c1, 11, ["GreenMimic", "RedMimic"]]
- [0x00d1, 5, ["GreenMimic", "RedMimic"]]
- [0x00d1, 6, ["GreenMimic", "RedMimic"]]
# the following are all slightly in the wall on spawn - not too applicable right now, these don't drop anyway
- [0x0064, 0, ["Leever"]]
- [0x00e5, 3, ["Wizzrobe"]]
- [0x00e5, 4, ["Leever", "Wizzrobe"]]
- [0x00e5, 5, ["Leever", "Wizzrobe"]]
# the pit one in 0xe6 room is in the pit section
- [0x00e6, 1, ["Leever", "Wizzrobe"]]
- [0x00e6, 2, ["Leever", "Wizzrobe"]]
- [0x00e6, 3, ["Leever", "Wizzrobe"]]
- [0x00e6, 4, ["Leever", "Wizzrobe"]]
- [0x00e7, 0, ["Wizzrobe"]]
- [0x00e7, 1, ["Wizzrobe"]]
- [0x00e7, 2, ["Wizzrobe"]]
- [0x00e7, 3, ["Leever"]]
- [0x00e7, 4, ["Leever", "Wizzrobe"]]
- [0x00e7, 5, ["Leever", "Wizzrobe"]]
- [0x00e7, 6, ["Wizzrobe"]]
- [0x00f0, 2, ["Leever"]] # clipped away
- [0x00f0, 3, ["Leever"]]
- [0x00f0, 4, ["Leever"]]
- [0x00f0, 5, ["Leever"]]
- [0x00f0, 6, ["Leever"]]
- [0x00f0, 8, ["Leever"]]
- [0x00f1, 0, ["Leever", "Wizzrobe"]]
- [0x00f1, 1, ["Leever", "Wizzrobe"]]
- [0x00f1, 2, ["Wizzrobe"]]
- [0x00f1, 3, ["Wizzrobe"]]
- [0x00f1, 4, ["Wizzrobe"]]
- [0x00f1, 5, ["Wizzrobe"]]
- [0x00f1, 6, ["Leever", "Wizzrobe"]]
- [0x00f1, 7, ["Leever", "Wizzrobe"]]
- [0x00f1, 8, ["Leever", "Wizzrobe"]]
- [0x00f1, 9, ["Leever", "Wizzrobe"]]
+57 -8
View File
@@ -6,7 +6,7 @@ import random
import re
from CLI import parse_cli
from Fill import FillError
from Main import main, EnemizerError
from Main import main, export_yaml, EnemizerError
from Utils import local_path, output_path, open_file, update_deprecated_args
import source.classes.constants as CONST
from source.gui.randomize.multiworld import multiworld_page
@@ -68,6 +68,15 @@ def bottom_frame(self, parent, args=None):
self.widgets[key].pack(side=LEFT)
def generateRom():
guiargs = create_guiargs(parent)
argsDump = vars(guiargs)
from Gui import save_settings
if parent.randomSprite.get():
argsDump['sprite'] = 'random'
elif argsDump['sprite']:
argsDump['sprite'] = argsDump['sprite'].name
save_settings(parent, argsDump, "last.json")
guiargs = create_guiargs(parent)
# get default values for missing parameters
for k,v in vars(parse_cli(['--multi', str(guiargs.multi)])).items():
@@ -141,9 +150,45 @@ def bottom_frame(self, parent, args=None):
# button
self.widgets[widget].type = "button"
self.widgets[widget].pieces["button"] = Button(self, text='Generate Patched Rom', command=generateRom)
self.widgets[widget].pieces["button"] = Button(self, command=generateRom)
# button: pack
self.widgets[widget].pieces["button"].pack(side=LEFT)
self.widgets[widget].pieces["button"].configure(bg="#CCCCCC")
def exportYaml():
guiargs = create_guiargs(parent)
# get default values for missing parameters
for k,v in vars(parse_cli(['--multi', str(guiargs.multi)])).items():
if k not in vars(guiargs):
setattr(guiargs, k, v)
elif type(v) is dict: # use same settings for every player
setattr(guiargs, k, {player: getattr(guiargs, k) for player in range(1, guiargs.multi + 1)})
filename = None
try:
from tkinter import filedialog
filename = filedialog.asksaveasfilename(initialdir=guiargs.outputpath, title="Save file", filetypes=(("Yaml Files", (".yaml", ".yml")), ("All Files", "*")))
if filename is not None and filename != '':
guiargs.outputpath = parent.settings["outputpath"] = os.path.dirname(filename)
guiargs.outputname = os.path.splitext(os.path.basename(filename))[0]
export_yaml(args=guiargs, fish=parent.fish)
except (FillError, EnemizerError, Exception, RuntimeError) as e:
logging.exception(e)
messagebox.showerror(title="Error while exporting yaml", message=str(e))
else:
if filename is not None and filename != '':
successMsg = "File Exported"
# FIXME: English
messagebox.showinfo(title="Success", message=successMsg)
## Export Yaml Button
widget = "exportyaml"
self.widgets[widget] = Empty()
self.widgets[widget].pieces = {}
# button
self.widgets[widget].type = "button"
self.widgets[widget].pieces["button"] = Button(self, command=exportYaml)
self.widgets[widget].pieces["button"].pack(side=LEFT)
def open_output():
if output_path.cached_path is None:
@@ -161,12 +206,8 @@ def bottom_frame(self, parent, args=None):
args.outputpath = parent.settings["outputpath"] = folder_selected
## Output Button
# widget ID
widget = "outputdir"
# Empty object
self.widgets[widget] = Empty()
# pieces
self.widgets[widget].pieces = {}
# storagevar
@@ -174,8 +215,16 @@ def bottom_frame(self, parent, args=None):
# button
self.widgets[widget].type = "button"
self.widgets[widget].pieces["button"] = Button(self, text='Open Output Directory', command=select_output)
# button: pack
self.widgets[widget].pieces["button"] = Button(self, command=select_output)
self.widgets[widget].pieces["button"].pack(side=RIGHT)
## Save Settings Button
widget = "savesettings"
self.widgets[widget] = Empty()
self.widgets[widget].pieces = {}
# button
self.widgets[widget].type = "button"
self.widgets[widget].pieces["button"] = Button(self)
self.widgets[widget].pieces["button"].pack(side=RIGHT)
## Documentation Button
+16
View File
@@ -158,6 +158,22 @@ def loadcliargs(gui, args, settings=None):
label = fish.translate("gui","gui",mainpage + '.' + subpage + '.' + widget)
gui.pages[mainpage].pages[subpage].widgets[widget].pieces["button"].configure(text=label)
# Set Export Yaml button
mainpage = "bottom"
subpage = "content"
widget = "exportyaml"
# set textbox/frame label
label = fish.translate("gui","gui",mainpage + '.' + subpage + '.' + widget)
gui.pages[mainpage].pages[subpage].widgets[widget].pieces["button"].configure(text=label)
# Set Save Settings button
mainpage = "bottom"
subpage = "content"
widget = "savesettings"
# set textbox/frame label
label = fish.translate("gui","gui",mainpage + '.' + subpage + '.' + widget)
gui.pages[mainpage].pages[subpage].widgets[widget].pieces["button"].configure(text=label)
# Set Output Directory button
mainpage = "bottom"
subpage = "content"
+9 -4
View File
@@ -1317,7 +1317,7 @@ def do_mandatory_connections(avail, entrances, cave_options, must_exit):
invalid_connections = Must_Exit_Invalid_Connections.copy()
invalid_cave_connections = defaultdict(set)
if avail.world.logic[avail.player] in ['owglitches', 'nologic']:
if avail.world.logic[avail.player] in ['owglitches', 'hybridglitches', 'nologic']:
import OverworldGlitchRules
for entrance in OverworldGlitchRules.get_non_mandatory_exits(avail.world, avail.player):
invalid_connections[entrance] = set()
@@ -1686,13 +1686,18 @@ def connect_exit(exit_name, entrancename, avail):
if exit.connected_region is not None:
exit.connected_region.entrances.remove(exit)
exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1])
dest_region = entrance.parent_region
if dest_region.name == 'Pyramid Crack':
# Needs to logically exit into greater Pyramid Area
dest_region = entrance.parent_region.entrances[0].parent_region
exit.connect(dest_region, door_addresses[entrance.name][1], exit_ids[exit.name][1])
if exit_name != 'Chris Houlihan Room Exit':
if avail.coupled:
avail.entrances.remove(entrancename)
avail.exits.remove(exit_name)
world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player)
logging.getLogger('').debug(f'Connected (exit) {entrance.name} to {exit.name}')
logging.getLogger('').debug(f'Connected (exit) {exit.name} to {entrance.name}')
def connect_two_way(entrancename, exit_name, avail):
@@ -2659,7 +2664,7 @@ door_addresses = {'Links House': (0x00, (0x0104, 0x2c
'Mire Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000), 0x00),
'Mire Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000), 0x00),
'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Dark Death Mountain Shop': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00),
'Dark Death Mountain Shop': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00),
'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000), 0x00),
'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00),
'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000), 0x00),
+4 -2
View File
@@ -46,8 +46,9 @@ def roll_settings(weights):
ret.algorithm = get_choice('algorithm')
glitch_map = {'none': 'noglitches', 'no_logic': 'nologic', 'owglitches': 'owglitches',
'owg': 'owglitches', 'minorglitches': 'minorglitches'}
glitch_map = {'none': 'noglitches', 'minorglitches': 'minorglitches', 'no_logic': 'nologic',
'hmg': 'hybridglitches', 'hybridglitches': 'hybridglitches',
'owg': 'owglitches', 'owglitches': 'owglitches'}
glitches_required = get_choice('glitches_required')
if glitches_required is not None:
if glitches_required not in glitch_map.keys():
@@ -114,6 +115,7 @@ def roll_settings(weights):
ret.pottery = 'keys' if ret.pottery == 'none' and keydropshuffle else ret.pottery
ret.colorizepots = get_choice_default('colorizepots', default='on') == 'on'
ret.shufflepots = get_choice('pot_shuffle') == 'on'
ret.aga_randomness = get_choice('aga_randomness') == 'on'
ret.mixed_travel = get_choice('mixed_travel') if 'mixed_travel' in weights else 'prevent'
ret.standardize_palettes = (get_choice('standardize_palettes') if 'standardize_palettes' in weights
else 'standardize')
+35
View File
@@ -0,0 +1,35 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: vanilla
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
placements:
1:
Ice Palace - Compass Chest: Fire Rod
Ice Palace - Freezor Chest: Bombos
+42
View File
@@ -0,0 +1,42 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: vanilla
start_inventory:
1:
- Flippers
- Lamp
- Tempered Sword
- Boss Heart Container
- Boss Heart Container
- Boss Heart Container
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
placements:
1:
Swamp Palace - Big Chest: Hammer
+34
View File
@@ -0,0 +1,34 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: vanilla
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
placements:
1:
Palace of Darkness - Shooter Room: Moon Pearl
+42
View File
@@ -0,0 +1,42 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: vanilla
start_inventory:
1:
- Flippers
- Lamp
- Tempered Sword
- Boss Heart Container
- Boss Heart Container
- Boss Heart Container
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
placements:
1:
Swamp Palace - Big Chest: Magic Mirror
+44
View File
@@ -0,0 +1,44 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: crossed
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
entrances:
1:
entrances:
Dark Lake Hylia Ledge Hint: Dark World Hammer Peg Cave
exits:
Links House: Chris Houlihan Room Exit
two-way:
Dark Lake Hylia Ledge Fairy: Palace of Darkness Exit
Lake Hylia Fortune Teller: Spectacle Rock Cave Exit
Links House: Links House Exit
placements:
1:
Peg Cave: Moon Pearl
@@ -0,0 +1,55 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: crossed
start_inventory:
1:
- Hookshot
- Lamp
- Hammer
- Magic Mirror
- Tempered Sword
- Boss Heart Container
- Boss Heart Container
- Boss Heart Container
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
entrances:
1:
entrances:
Dark Lake Hylia Ledge Hint: Dark World Hammer Peg Cave
exits:
Links House: Chris Houlihan Room Exit
two-way:
Dark Lake Hylia Ledge Fairy: Swamp Palace Exit
Lake Hylia Fortune Teller: Misery Mire Exit
Links House: Links House Exit
placements:
1:
Peg Cave: Moon Pearl
@@ -0,0 +1,44 @@
meta:
players: 1
settings:
1:
accessibility: items
door_shuffle: vanilla
logic: hybridglitches
mode: open
shuffle: vanilla
start_inventory:
1:
- Hookshot
- Lamp
- Hammer
- Magic Mirror
- Tempered Sword
- Boss Heart Container
- Boss Heart Container
- Boss Heart Container
doors:
1:
doors:
Hera Beetles WS: Hera Startile Corner ES
Hera Startile Corner ES: Hera Beetles WS
Hera Startile Corner NW: Hera Startile Wide SW
Hera Startile Wide SW: Hera Startile Corner NW
Skull 1 Lobby ES: Skull Map Room WS
Skull 2 West Lobby ES: Skull Small Hall WS
Skull 2 West Lobby NW: Skull X Room SW
Skull Big Chest N: Skull Pull Switch S
Skull Compass Room WS: Skull Left Drop ES
Skull Final Drop WS: Skull Spike Corner ES
Skull Left Drop ES: Skull Compass Room WS
Skull Map Room WS: Skull 1 Lobby ES
Skull Pot Circle WN: Skull Pull Switch EN
Skull Pull Switch EN: Skull Pot Circle WN
Skull Pull Switch S: Skull Big Chest N
Skull Small Hall WS: Skull 2 West Lobby ES
Skull Spike Corner ES: Skull Final Drop WS
Skull X Room SW: Skull 2 West Lobby NW
lobbies: {}
# placements:
# 1:
# Swamp Palace - Entrance: Boss Heart Container
@@ -0,0 +1,34 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
shuffle: crossed
start_inventory:
1:
- Flippers
- Pegasus Boots
- Progressive Sword
- Hammer
- Progressive Glove
- Progressive Glove
- Fire Rod
- Book of Mudora
- Bottle
- Magic Mirror
- Lamp
advanced_placements:
1:
- type: Verification
item: Moon Pearl
locations:
Pyramid Fairy - Left: True
entrances:
1:
entrances:
Skull Woods Final Section: Pyramid Fairy
two-way:
Chicken House: Two Brothers House Exit (West)
Skull Woods Second Section Door (West): Two Brothers House Exit (East)
+17
View File
@@ -0,0 +1,17 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
start_inventory:
1:
- Flippers
- Moon Pearl
- Progressive Sword
- Hammer
- Progressive Glove
- Progressive Glove
placements:
1:
Ice Palace - Map Chest: Bombos
Ice Palace - Iced T Room: Fire Rod
@@ -0,0 +1,20 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
start_inventory:
1:
- Pegasus Boots
- Moon Pearl
- Progressive Sword
advanced_placements:
1:
- type: Verification
item: Flippers
locations:
Zora's Ledge: True
Hobo: True
Ice Palace - Boss: True
Swamp Palace - Entrance: False
+29
View File
@@ -0,0 +1,29 @@
meta:
players: 1
settings:
1:
logic: owglitches
start_inventory:
1:
- Pegasus Boots
- Moon Pearl
- Progressive Sword
- Flippers
placements:
1:
Peg Cave: Magic Mirror
advanced_placements:
1:
- type: Verification
item: Hammer
locations:
Link's House: True
Magic Bat: False
advanced_placements:
1:
- type: Verification
item: Progressive Glove
locations:
Link's House: True
Ice Palace - Freezor Chest: False
+26
View File
@@ -0,0 +1,26 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
start_inventory:
1:
- Flippers
- Moon Pearl
- Progressive Sword
- Lamp
- Magic Mirror
- Ether
- Quake
- Bombos
advanced_placements:
1:
- type: Verification
item: Big Key (Tower of Hera)
locations:
Tower of Hera - Big Key Chest: True
Tower of Hera - Basement Cage: True
Tower of Hera - Map Chest: True
Tower of Hera - Compass Chest: True
Tower of Hera - Big Chest: True
Tower of Hera - Boss: True
@@ -0,0 +1,26 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
mode: inverted
shuffle: crossed
start_inventory:
1:
- Pegasus Boots
- Progressive Sword
- Hammer
- Fire Rod
placements:
1:
Desert Palace - Boss: Moon Pearl
entrances:
1:
two-way:
Skull Woods Final Section: Desert Palace Exit (West)
Skull Woods Second Section Door (West): Desert Palace Exit (East)
Thieves Town: Thieves Town Exit
Hyrule Castle Entrance (East): Desert Palace Exit (South)
Hyrule Castle Entrance (West): Desert Palace Exit (North)
@@ -0,0 +1,31 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
mode: inverted
start_inventory:
1:
- Flippers
- Progressive Sword
- Progressive Sword
- Book of Mudora
- Lamp
- Magic Mirror
- Ether
- Quake
- Bombos
advanced_placements:
1:
- type: Verification
item: Moon Pearl
locations:
Tower of Hera - Big Chest: True
Desert Palace - Big Chest: True
Eastern Palace - Big Chest: True
Bombos Tablet: True
Cave 45: True
+48
View File
@@ -0,0 +1,48 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
start_inventory:
1:
- Pegasus Boots
- Flippers
- Fire Rod
- Book of Mudora
- Progressive Sword
- Progressive Sword
- Lamp
- Magic Mirror
- Ether
- Quake
- Bombos
advanced_placements:
1:
- type: Verification
item: Moon Pearl
locations:
Skull Woods - Compass Chest: True
Skull Woods - Bridge Room: True
Palace of Darkness - Shooter Room: True
Palace of Darkness - The Arena - Bridge: True
Palace of Darkness - Stalfos Basement: True
Palace of Darkness - Big Key Chest: True
Palace of Darkness - The Arena - Ledge: True
Palace of Darkness - Map Chest: True
Palace of Darkness - Compass Chest: True
Palace of Darkness - Dark Basement - Left: True
Palace of Darkness - Dark Basement - Right: True
Palace of Darkness - Dark Maze - Top: True
Palace of Darkness - Dark Maze - Bottom: True
Palace of Darkness - Big Chest: True
Palace of Darkness - Harmless Hellway: True
Palace of Darkness - Boss: True
Bombos Tablet: True
C-Shaped House: True
Pyramid Fairy - Left: True
Swamp Palace - Entrance: False
Thieves' Town - Map Chest: False
+25
View File
@@ -0,0 +1,25 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
start_inventory:
1:
- Flippers
- Pegasus Boots
- Progressive Sword
- Hammer
- Progressive Glove
- Progressive Glove
- Fire Rod
- Book of Mudora
- Bottle
- Magic Mirror
- Lamp
advanced_placements:
1:
- type: Verification
item: Moon Pearl
locations:
Skull Woods - Bridge Room: True
+43
View File
@@ -0,0 +1,43 @@
meta:
players: 1
settings:
1:
logic: hybridglitches
start_inventory:
1:
- Flippers
- Moon Pearl
- Progressive Sword
- Lamp
- Magic Mirror
- Ether
- Quake
- Bombos
advanced_placements:
1:
- type: Verification
item: Small Key (Swamp Palace)
locations:
Swamp Palace - Entrance: True
Swamp Palace - Map Chest: True
Swamp Palace - Big Chest: True
Swamp Palace - Compass Chest: True
Swamp Palace - West Chest: True
Swamp Palace - Big Key Chest: True
Swamp Palace - Flooded Room - Left: True
Swamp Palace - Flooded Room - Right: True
Swamp Palace - Waterfall Room: True
Swamp Palace - Boss: True
- type: Verification
item: Big Key (Swamp Palace)
locations:
Swamp Palace - Entrance: True
Swamp Palace - Map Chest: True
Swamp Palace - Big Chest: True
Swamp Palace - Compass Chest: True
Swamp Palace - West Chest: True
Swamp Palace - Big Key Chest: True
Swamp Palace - Flooded Room - Left: True
Swamp Palace - Flooded Room - Right: True
Swamp Palace - Waterfall Room: True
Swamp Palace - Boss: True