Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -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
@@ -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
|
||||
@@ -1168,6 +1204,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)
|
||||
@@ -1345,6 +1389,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:
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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'
|
||||
],
|
||||
|
||||
+90
-91
@@ -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,8 +279,9 @@ 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.
|
||||
for data in get_mirror_offset_spots(world, player):
|
||||
set_owg_rules(player, world, [data[0:3]], lambda state: state.has_Mirror(player) and state.can_boots_clip_lw(player) and state.can_reach(data[3], None, player))
|
||||
@@ -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
@@ -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
@@ -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
@@ -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()}
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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)
|
||||
@@ -1683,13 +1699,32 @@ def set_bunny_rules(world, player, inverted):
|
||||
return region.is_dark_world
|
||||
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]
|
||||
|
||||
@@ -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",
|
||||
)
|
||||
+181
-153
@@ -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,18 +620,57 @@ 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
|
||||
PLX : INX : INX : INX
|
||||
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
@@ -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
|
||||
|
||||
|
||||
@@ -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": {},
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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:
|
||||
|
||||
+29
-29
@@ -263,7 +263,7 @@ def output_song_data(rom, filepath, outfilebase):
|
||||
if tracks > 0:
|
||||
outfile.write(' ' * tracks)
|
||||
outfile.write(f' = {rom.read_byte(snes_to_pc(next(iter(change.tracks.values()))[0])):02X}')
|
||||
|
||||
|
||||
|
||||
def randomize_songinstruments(rom):
|
||||
# categorize instruments in pools
|
||||
@@ -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],
|
||||
|
||||
@@ -148,7 +148,7 @@ SETTINGSTOPROCESS = {
|
||||
"createrom": "create_rom",
|
||||
"calcplaythrough": "calc_playthrough",
|
||||
"print_custom_yaml": "print_custom_yaml",
|
||||
"saveonexit": "saveonexit"
|
||||
"settingsonload": "settingsonload"
|
||||
}
|
||||
},
|
||||
"startinventory": {
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user