Merge remote-tracking branch 'origin/DoorDev' into DoorDev

This commit is contained in:
aerinon
2019-11-16 21:40:15 -07:00
11 changed files with 713 additions and 243 deletions

View File

@@ -3,11 +3,13 @@ import collections
from collections import defaultdict
import logging
import operator as op
import time
from functools import reduce
from BaseClasses import RegionType, Door, DoorType, Direction, Sector, Polarity, CrystalBarrier
from Dungeons import hyrule_castle_regions, eastern_regions, desert_regions, hera_regions, tower_regions, pod_regions
from Dungeons import dungeon_regions, region_starts, split_region_starts, dungeon_keys, dungeon_bigs, flexible_starts
from Dungeons import drop_entrances
from RoomData import DoorKind, PairedDoor
from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon
@@ -42,7 +44,7 @@ def link_doors(world, player):
connect_two_way(world, entrance, ext, player)
for ent, ext in default_one_way_connections:
connect_one_way(world, ent, ext, player)
world.key_logic[player] = {} # todo: actual vanilla key logic
vanilla_key_logic(world, player)
elif world.doorShuffle == 'basic':
within_dungeon(world, player)
elif world.doorShuffle == 'crossed':
@@ -105,6 +107,28 @@ def create_door_spoiler(world, player):
# logger.debug('Unpaired Doors: %s not paired with %s (p%d)', dp.door_a, dp.door_b, player)
def vanilla_key_logic(world, player):
sectors = []
for dungeon in [dungeon for dungeon in world.dungeons if dungeon.player == player]:
sector = Sector()
sector.name = dungeon.name
sector.regions.extend(convert_regions(dungeon.regions, world, player))
sectors.append(sector)
overworld_prep(world, player)
entrances_map, potentials, connections = determine_entrance_list(world, player)
for sector in sectors:
start_regions = convert_regions(entrances_map[sector.name], world, player)
doors = convert_key_doors(default_small_key_doors[sector.name], world, player)
key_layout = KeyLayout(sector, start_regions, doors)
valid = validate_key_layout(key_layout, world, player)
if not valid:
raise Exception('Vanilla key layout not valid %s' % sector.name)
if player not in world.key_logic.keys():
world.key_logic[player] = {}
world.key_logic[player][sector.name] = key_layout.key_logic
# some useful functions
oppositemap = {
Direction.South: Direction.North,
@@ -120,6 +144,16 @@ def switch_dir(direction):
return oppositemap[direction]
def convert_key_doors(key_doors, world, player):
result = []
for d in key_doors:
if type(d) is tuple:
result.append((world.get_door(d[0], player), world.get_door(d[1], player)))
else:
result.append(world.get_door(d, player))
return result
def connect_simple_door(world, exit_name, region_name, player):
region = world.get_region(region_name, player)
world.get_entrance(exit_name, player).connect(region)
@@ -196,7 +230,7 @@ def fix_big_key_doors_with_ugly_smalls(world, player):
def remove_ugly_small_key_doors(world, player):
for d in ['Eastern Hint Tile Blocked Path SE', 'Eastern Darkness S', 'Thieves Hallway SE', 'Mire Left Bridge S',
'TR Lava Escape SE']:
'TR Lava Escape SE', 'GT Hidden Spikes SE']:
door = world.get_door(d, player)
room = world.get_room(door.roomIndex, player)
room.change(door.doorListPos, DoorKind.Normal)
@@ -206,7 +240,7 @@ def remove_ugly_small_key_doors(world, player):
def unpair_big_key_doors(world, player):
problematic_bk_doors = ['Eastern Courtyard N', 'Eastern Big Key NE', 'Thieves BK Corner NE', 'Mire BK Door Room N',
'TR Dodgers NE']
'TR Dodgers NE', 'GT Dash Hall NE']
for paired_door in world.paired_doors[player]:
if paired_door.door_a in problematic_bk_doors or paired_door.door_b in problematic_bk_doors:
paired_door.pair = False
@@ -254,6 +288,7 @@ def within_dungeon(world, player):
for key, sector_list, entrance_list in dungeon_sectors:
origin_list = list(entrance_list)
find_enabled_origins(sector_list, enabled_entrances, origin_list)
remove_drop_origins(origin_list)
ds = generate_dungeon(sector_list, origin_list, world, player)
find_new_entrances(ds, connections, potentials, enabled_entrances)
ds.name = key
@@ -268,8 +303,10 @@ def within_dungeon(world, player):
check_required_paths(paths, world, player)
# shuffle_key_doors for dungeons
start = time.process_time()
for sector, entrances in world.dungeon_layouts[player].values():
shuffle_key_doors(sector, entrances, world, player)
logging.getLogger('').info('Key door shuffle time: %s', time.process_time()-start)
def determine_entrance_list(world, player):
@@ -307,6 +344,10 @@ def find_enabled_origins(sectors, enabled, entrance_list):
entrance_list.append(region.name)
def remove_drop_origins(entrance_list):
return [x for x in entrance_list if x not in drop_entrances]
def find_new_entrances(sector, connections, potentials, enabled):
for region in sector.regions:
if region.name in connections.keys() and connections[region.name] in potentials.keys():
@@ -732,6 +773,8 @@ def valid_region_to_explore(region, world):
def shuffle_key_doors(dungeon_sector, entrances, world, player):
logger = logging.getLogger('')
logger.info('Shuffling Key doors for %s', dungeon_sector.name)
start_regions = convert_regions(entrances, world, player)
# count number of key doors - this could be a table?
num_key_doors = 0
@@ -772,30 +815,45 @@ def shuffle_key_doors(dungeon_sector, entrances, world, player):
paired_candidates = build_pair_list(flat_candidates)
if len(paired_candidates) < num_key_doors:
num_key_doors = len(paired_candidates) # reduce number of key doors
logging.getLogger('').info('Lowering key door count because not enough candidates: %s', dungeon_sector.name)
logger.info('Lowering key door count because not enough candidates: %s', dungeon_sector.name)
random.shuffle(paired_candidates)
combinations = ncr(len(paired_candidates), num_key_doors)
itr = 0
proposal = kth_combination(itr, paired_candidates, num_key_doors)
key_logic = KeyLogic(dungeon_sector.name)
while not validate_key_layout(dungeon_sector, start_regions, proposal, key_logic, world, player):
key_layout = KeyLayout(dungeon_sector, start_regions, proposal)
while not validate_key_layout(key_layout, world, player):
itr += 1
if itr >= combinations:
logging.getLogger('').info('Lowering key door count because no valid layouts: %s', dungeon_sector.name)
logger.info('Lowering key door count because no valid layouts: %s', dungeon_sector.name)
num_key_doors -= 1
if num_key_doors < 0:
raise Exception('Bad dungeon %s - 0 key doors not valid' % dungeon_sector.name)
combinations = ncr(len(paired_candidates), num_key_doors)
itr = 0
proposal = kth_combination(itr, paired_candidates, num_key_doors)
key_logic = KeyLogic(dungeon_sector.name)
key_layout.reset(proposal)
# make changes
if player not in world.key_logic.keys():
world.key_logic[player] = {}
world.key_logic[player][dungeon_sector.name] = key_logic
world.key_logic[player][dungeon_sector.name] = key_layout.key_logic
reassign_key_doors(current_doors, proposal, world, player)
class KeyLayout(object):
def __init__(self, sector, starts, proposal):
self.sector = sector
self.start_regions = starts
self.proposal = proposal
self.key_logic = KeyLogic(sector.name)
self.checked_states = {}
def reset(self, proposal):
self.proposal = proposal
self.key_logic = KeyLogic(self.sector.name)
self.checked_states = {}
class KeyLogic(object):
def __init__(self, dungeon_name):
@@ -890,21 +948,19 @@ def ncr(n, r):
return numerator / denominator
def validate_key_layout(sector, start_regions, key_door_proposal, key_logic, world, player):
flat_proposal = flatten_pair_list(key_door_proposal)
def validate_key_layout(key_layout, world, player):
flat_proposal = flatten_pair_list(key_layout.proposal)
state = ExplorationState()
state.key_locations = len(world.get_dungeon(sector.name, player).small_keys)
state.big_key_special = world.get_region('Hyrule Dungeon Cellblock', player) in sector.regions
state.key_locations = len(world.get_dungeon(key_layout.sector.name, player).small_keys)
state.big_key_special = world.get_region('Hyrule Dungeon Cellblock', player) in key_layout.sector.regions
# Everything in a start region is in key region 0.
for region in start_regions:
for region in key_layout.start_regions:
state.visit_region(region, key_checks=True)
state.add_all_doors_check_keys(region, flat_proposal, world, player)
checked_states = set()
return validate_key_layout_r(state, flat_proposal, checked_states, key_logic, world, player)
return validate_key_layout_r(state, key_layout, flat_proposal, world, player)
def validate_key_layout_r(state, flat_proposal, checked_states, key_logic, world, player):
def validate_key_layout_r(state, key_layout, flat_proposal, world, player):
# improvements: remove recursion to make this iterative
# store a cache of various states of opened door to increase speed of checks - many are repetitive
while len(state.avail_doors) > 0:
@@ -932,13 +988,15 @@ def validate_key_layout_r(state, flat_proposal, checked_states, key_logic, world
state_copy.avail_doors.extend(state.big_doors)
state_copy.big_doors.clear()
code = state_id(state_copy, flat_proposal)
if code not in checked_states:
valid = validate_key_layout_r(state_copy, flat_proposal, checked_states, key_logic, world, player)
if valid:
checked_states.add(code)
if code not in key_layout.checked_states.keys():
valid = validate_key_layout_r(state_copy, key_layout, flat_proposal, world, player)
key_layout.checked_states[code] = valid
else:
valid = key_layout.checked_states[code]
if not valid:
return False
if smalls_avail and available_small_locations > 0:
key_logic = key_layout.key_logic
key_rule_num = min(available_small_locations, count_unique_doors(state.small_doors)) + state.used_smalls
if key_rule_num == ttl_locations:
key_logic.bk_restricted.extend([x for x in get_valid_small_key_locations(state) if x not in key_logic.bk_restricted])
@@ -963,10 +1021,11 @@ def validate_key_layout_r(state, flat_proposal, checked_states, key_logic, world
state_copy.used_locations += 1
state_copy.used_smalls += 1
code = state_id(state_copy, flat_proposal)
if code not in checked_states:
valid = validate_key_layout_r(state_copy, flat_proposal, checked_states, key_logic, world, player)
if valid:
checked_states.add(code)
if code not in key_layout.checked_states.keys():
valid = validate_key_layout_r(state_copy, key_layout, flat_proposal, world, player)
key_layout.checked_states[code] = valid
else:
valid = key_layout.checked_states[code]
if not valid:
return False
return valid
@@ -1138,6 +1197,7 @@ def determine_required_paths(world):
'Ice Palace': ['Ice Boss'],
'Misery Mire': ['Mire Boss'],
'Turtle Rock': ['TR Boss'],
'Ganons Tower': ['GT Agahnim 2']
}
if world.shuffle == 'vanilla':
paths['Skull Woods'].insert(0, 'Skull 2 West Lobby')
@@ -1153,61 +1213,65 @@ def determine_required_paths(world):
def overworld_prep(world, player):
find_inaccessible_regions(world, player)
add_inaccessible_doors(world, player)
# todo : multiplayer?
def find_inaccessible_regions(world, player):
if world.mode != 'inverted':
if world.mode == 'standard':
world.inaccessible_regions.append('Hyrule Castle Ledge') # maybe only with er off
world.inaccessible_regions.append('Sewer Drop')
world.inaccessible_regions.append('Skull Woods Forest (West)')
world.inaccessible_regions.append('Dark Death Mountain Ledge')
world.inaccessible_regions.append('Dark Death Mountain Isolated Ledge')
world.inaccessible_regions.append('Desert Palace Lone Stairs')
world.inaccessible_regions.append('Bumper Cave Ledge')
world.inaccessible_regions.append('Death Mountain Floating Island (Dark World)')
start_regions = ['Links House', 'Sanctuary']
else:
world.inaccessible_regions.append('Desert Ledge')
# world.inaccessible_regions.append('Hyrule Castle Ledge') # accessible via aga 1?
world.inaccessible_regions.append('Desert Palace Lone Stairs')
world.inaccessible_regions.append('Death Mountain Return Ledge')
world.inaccessible_regions.append('Maze Race Ledge')
if world.shuffle == 'vanilla':
skull_doors = [
Door(player, 'Skull Woods Second Section Exit (West)', DoorType.Logical),
Door(player, 'Skull Woods Second Section Door (West)', DoorType.Logical),
Door(player, 'Skull Woods Second Section Hole', DoorType.Logical),
Door(player, 'Skull Woods Final Section', DoorType.Logical)
]
world.doors += skull_doors
connect_door_only(world, skull_doors[0].name, 'Skull Woods Forest (West)', player)
connect_door_only(world, skull_doors[1].name, 'Skull 2 West Lobby', player)
connect_door_only(world, skull_doors[2].name, 'Skull Back Drop', player)
connect_door_only(world, skull_doors[3].name, 'Skull 3 Lobby', player)
tr_doors = [
Door(player, 'Turtle Rock Ledge Exit (West)', DoorType.Logical),
Door(player, 'Turtle Rock Ledge Exit (East)', DoorType.Logical),
Door(player, 'Dark Death Mountain Ledge (East)', DoorType.Logical),
Door(player, 'Dark Death Mountain Ledge (West)', DoorType.Logical),
Door(player, 'Turtle Rock Isolated Ledge Exit', DoorType.Logical),
Door(player, 'Turtle Rock Isolated Ledge Entrance', DoorType.Logical),
]
world.doors += tr_doors
connect_door_only(world, tr_doors[0].name, 'Dark Death Mountain Ledge', player)
connect_door_only(world, tr_doors[1].name, 'Dark Death Mountain Ledge', player)
connect_door_only(world, tr_doors[2].name, 'TR Big Chest Entrance', player)
connect_door_only(world, tr_doors[3].name, 'TR Lazy Eyes', player)
connect_door_only(world, tr_doors[4].name, 'Dark Death Mountain Isolated Ledge', player)
connect_door_only(world, tr_doors[5].name, 'TR Eye Bridge', player)
if world.mode == 'standard':
castle_doors = [
Door(player, 'Hyrule Castle Exit (West)', DoorType.Logical),
Door(player, 'Hyrule Castle Exit (East)', DoorType.Logical),
Door(player, 'Hyrule Castle Entrance (East)', DoorType.Logical),
Door(player, 'Hyrule Castle Entrance (West)', DoorType.Logical)
]
world.doors += castle_doors
connect_door_only(world, castle_doors[0].name, 'Hyrule Castle Ledge', player)
connect_door_only(world, castle_doors[1].name, 'Hyrule Castle Ledge', player)
connect_door_only(world, castle_doors[2].name, 'Hyrule Castle East Lobby', player)
connect_door_only(world, castle_doors[3].name, 'Hyrule Castle West Lobby', player)
start_regions = ['Inverted Links House', 'Inverted Dark Sanctuary']
regs = convert_regions(start_regions, world, player)
all_regions = set([r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon])
visited_regions = set()
queue = collections.deque(regs)
while len(queue) > 0:
next_region = queue.popleft()
visited_regions.add(next_region)
for ext in next_region.exits:
connect = ext.connected_region
if connect is not None and connect.type is not RegionType.Dungeon and connect not in queue and connect not in visited_regions:
queue.append(connect)
world.inaccessible_regions.extend([r.name for r in all_regions.difference(visited_regions) if r.type is not RegionType.Cave])
logger = logging.getLogger('')
logger.info('Inaccessible Regions:')
for r in world.inaccessible_regions:
logger.info('%s', r)
def add_inaccessible_doors(world, player):
if 'Skull Woods Forest (West)' in world.inaccessible_regions:
create_door(world, player, 'Skull Woods Second Section Door (West)', 'Skull Woods Forest (West)')
create_door(world, player, 'Skull Woods Second Section Hole', 'Skull Woods Forest (West)')
create_door(world, player, 'Skull Woods Final Section', 'Skull Woods Forest (West)')
if 'Dark Death Mountain Ledge' in world.inaccessible_regions:
create_door(world, player, 'Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge')
create_door(world, player, 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge')
create_door(world, player, 'Mimic Cave Mirror Spot', 'Dark Death Mountain Ledge')
if 'Mimic Cave Ledge' in world.inaccessible_regions:
create_door(world, player, 'Mimic Cave', 'Mimic Cave Ledge')
if 'Dark Death Mountain Isolated Ledge' in world.inaccessible_regions:
create_door(world, player, 'Turtle Rock Isolated Ledge Entrance', 'Dark Death Mountain Isolated Ledge')
if 'Death Mountain Floating Island (Dark World)' in world.inaccessible_regions:
create_door(world, player, 'Hookshot Cave Back Entrance', 'Death Mountain Floating Island (Dark World)')
# todo: desert palace lone stairs
if world.mode == 'standard' and 'Hyrule Castle Ledge' in world.inaccessible_regions:
create_door(world, player, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Ledge')
create_door(world, player, 'Hyrule Castle Entrance (West)', 'Hyrule Castle Ledge')
def create_door(world, player, entName, region_name):
connect = world.get_entrance(entName, player).connected_region
for ext in connect.exits:
if ext.connected_region is not None and ext.connected_region.name == region_name:
d = Door(player, ext.name, DoorType.Logical),
world.doors += d
connect_door_only(world, ext.name, ext.connected_region, player)
d = Door(player, entName, DoorType.Logical),
world.doors += d
connect_door_only(world, entName, connect, player)
def check_required_paths(paths, world, player):
@@ -1398,7 +1462,29 @@ logical_connections = [
('TR Pipe Ledge Drop Down', 'TR Pipe Pit'),
('TR Big Chest Gap', 'TR Big Chest Entrance'),
('TR Big Chest Entrance Gap', 'TR Big Chest'),
# ('', ''),
('GT Blocked Stairs Block Path', 'GT Big Chest'),
('GT Hookshot East-North Path', 'GT Hookshot North Platform'),
('GT Hookshot East-South Path', 'GT Hookshot South Platform'),
('GT Hookshot North-East Path', 'GT Hookshot East Platform'),
('GT Hookshot North-South Path', 'GT Hookshot South Platform'),
('GT Hookshot South-East Path', 'GT Hookshot East Platform'),
('GT Hookshot South-North Path', 'GT Hookshot North Platform'),
('GT Hookshot Platform Blue Barrier', 'GT Hookshot South Entry'),
('GT Hookshot Entry Blue Barrier', 'GT Hookshot South Platform'),
('GT Double Switch Orange Barrier', 'GT Double Switch Switches'),
('GT Double Switch Orange Barrier 2', 'GT Double Switch Key Spot'),
('GT Double Switch Transition Blue', 'GT Double Switch Exit'),
('GT Double Switch Blue Path', 'GT Double Switch Transition'),
('GT Double Switch Orange Path', 'GT Double Switch Entry'),
('GT Double Switch Key Blue Path', 'GT Double Switch Exit'),
('GT Double Switch Key Orange Path', 'GT Double Switch Entry'),
('GT Double Switch Blue Barrier', 'GT Double Switch Key Spot'),
('GT Warp Maze - Pit Section Warp Spot', 'GT Warp Maze - Pit Exit Warp Spot'),
('GT Warp Maze Exit Section Warp Spot', 'GT Warp Maze - Pit Exit Warp Spot'),
('GT Firesnake Room Hook Path', 'GT Firesnake Room Ledge'),
('GT Left Moldorm Ledge Drop Down', 'GT Moldorm'),
('GT Right Moldorm Ledge Drop Down', 'GT Moldorm'),
('GT Moldorm Gap', 'GT Validation')
]
vanilla_logical_connections = [
@@ -1451,7 +1537,14 @@ spiral_staircases = [
('Mire Falling Foes Up Stairs', 'Mire Firesnake Skip Down Stairs'),
('TR Chain Chomps Down Stairs', 'TR Pipe Pit Up Stairs'),
('TR Crystaroller Down Stairs', 'TR Dark Ride Up Stairs'),
# ('', ''),
('GT Lobby Left Down Stairs', 'GT Torch Up Stairs'),
('GT Lobby Up Stairs', 'GT Crystal Paths Down Stairs'),
('GT Lobby Right Down Stairs', 'GT Hope Room Up Stairs'),
('GT Blocked Stairs Down Stairs', 'GT Four Torches Up Stairs'),
('GT Cannonball Bridge Up Stairs', 'GT Gauntlet 1 Down Stairs'),
('GT Quad Pot Up Stairs', 'GT Wizzrobes 1 Down Stairs'),
('GT Moldorm Pit Up Stairs', 'GT Right Moldorm Ledge Down Stairs'),
('GT Frozen Over Up Stairs', 'GT Brightly Lit Hall Down Stairs')
]
straight_staircases = [
@@ -1459,7 +1552,7 @@ straight_staircases = [
('Sewers Rope Room North Stairs', 'Sewers Dark Cross South Stairs'),
('Tower Catwalk North Stairs', 'Tower Antechamber South Stairs'),
('PoD Conveyor North Stairs', 'PoD Map Balcony South Stairs'),
('TR Crystal Maze North Stairs', 'TR Final Abyss South Stairs'),
('TR Crystal Maze North Stairs', 'TR Final Abyss South Stairs')
]
open_edges = [
@@ -1513,7 +1606,9 @@ falldown_pits = [
('Ice Backwards Room Hole', 'Ice Fairy'),
('Ice Antechamber Hole', 'Ice Boss'),
('Mire Attic Hint Hole', 'Mire BK Chest Ledge'),
# ('', ''),
('GT Bob\'s Room Hole', 'GT Ice Armos'),
('GT Falling Torches Hole', 'GT Staredown'),
('GT Moldorm Hole', 'GT Moldorm Pit')
]
dungeon_warps = [
@@ -1526,15 +1621,30 @@ dungeon_warps = [
('Ice Fairy Warp', 'Ice Anti-Fairy'),
('Mire Lone Warp Warp', 'Mire BK Door Room'),
('Mire Warping Pool Warp', 'Mire Square Rail'),
# ('', ''),
('GT Compass Room Warp', 'GT Conveyor Star Pits'),
('GT Spike Crystals Warp', 'GT Firesnake Room'),
('GT Warp Maze - Left Section Warp', 'GT Warp Maze - Rando Rail'),
('GT Warp Maze - Mid Section Left Warp', 'GT Warp Maze - Main Rails'),
('GT Warp Maze - Mid Section Right Warp', 'GT Warp Maze - Main Rails'),
('GT Warp Maze - Right Section Warp', 'GT Warp Maze - Main Rails'),
('GT Warp Maze - Pit Exit Warp', 'GT Warp Maze - Pot Rail'),
('GT Warp Maze - Rail Choice Left Warp', 'GT Warp Maze - Left Section'),
('GT Warp Maze - Rail Choice Right Warp', 'GT Warp Maze - Mid Section'),
('GT Warp Maze - Rando Rail Warp', 'GT Warp Maze - Mid Section'),
('GT Warp Maze - Main Rails Best Warp', 'GT Warp Maze - Pit Section'),
('GT Warp Maze - Main Rails Mid Left Warp', 'GT Warp Maze - Mid Section'),
('GT Warp Maze - Main Rails Mid Right Warp', 'GT Warp Maze - Mid Section'),
('GT Warp Maze - Main Rails Right Top Warp', 'GT Warp Maze - Right Section'),
('GT Warp Maze - Main Rails Right Mid Warp', 'GT Warp Maze - Right Section'),
('GT Warp Maze - Pot Rail Warp', 'GT Warp Maze Exit Section'),
('GT Hidden Star Warp', 'GT Invisible Bridges')
]
ladders = [
('PoD Bow Statue Down Ladder', 'PoD Dark Pegs Up Ladder'),
('Ice Big Key Down Ladder', 'Ice Tongue Pull Up Ladder'),
('Ice Firebar Down Ladder', 'Ice Freezors Up Ladder'),
# ('', ''),
# ('', ''),
('GT Staredown Up Ladder', 'GT Falling Torches Down Ladder')
]
interior_doors = [
@@ -1679,7 +1789,33 @@ interior_doors = [
('TR Dash Room ES', 'TR Tongue Pull WS'),
('TR Dash Room NW', 'TR Crystaroller SW'),
('TR Tongue Pull NE', 'TR Rupees SE'),
# ('', ''),
('GT Torch EN', 'GT Hope Room WN'),
('GT Torch SW', 'GT Big Chest NW'),
('GT Tile Room EN', 'GT Speed Torch WN'),
('GT Speed Torch WS', 'GT Pots n Blocks ES'),
('GT Crystal Conveyor WN', 'GT Compass Room EN'),
('GT Conveyor Cross WN', 'GT Hookshot EN'),
('GT Hookshot ES', 'GT Map Room WS'),
('GT Double Switch EN', 'GT Spike Crystals WN'),
('GT Firesnake Room SW', 'GT Warp Maze (Rails) NW'),
('GT Ice Armos NE', 'GT Big Key Room SE'),
('GT Ice Armos WS', 'GT Four Torches ES'),
('GT Four Torches NW', 'GT Fairy Abyss SW'),
('GT Crystal Paths SW', 'GT Mimics 1 NW'),
('GT Mimics 1 ES', 'GT Mimics 2 WS'),
('GT Mimics 2 NE', 'GT Dash Hall SE'),
('GT Cannonball Bridge SE', 'GT Refill NE'),
('GT Gauntlet 1 WN', 'GT Gauntlet 2 EN'),
('GT Gauntlet 2 SW', 'GT Gauntlet 3 NW'),
('GT Gauntlet 4 SW', 'GT Gauntlet 5 NW'),
('GT Beam Dash WS', 'GT Lanmolas 2 ES'),
('GT Lanmolas 2 NW', 'GT Quad Pot SW'),
('GT Wizzrobes 1 SW', 'GT Dashing Bridge NW'),
('GT Dashing Bridge NE', 'GT Wizzrobes 2 SE'),
('GT Torch Cross ES', 'GT Staredown WS'),
('GT Falling Torches NE', 'GT Mini Helmasaur Room SE'),
('GT Mini Helmasaur Room WN', 'GT Bomb Conveyor EN'),
('GT Bomb Conveyor SW', 'GT Crystal Circles NW')
]
key_doors = [
@@ -1701,6 +1837,96 @@ key_doors = [
('PoD Falling Bridge WN', 'PoD Dark Maze EN'),
]
default_small_key_doors = {
'Hyrule Castle': [
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
('Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S'),
('Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon North Abyss Key Door N'),
('Hyrule Dungeon Armory Interior Key Door N', 'Hyrule Dungeon Armory Interior Key Door S')
],
'Eastern Palace': [
('Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN'),
'Eastern Darkness Up Stairs',
],
'Desert Palace': [
('Desert East Wing Key Door EN', 'Desert Compass Key Door WN'),
'Desert Tiles 1 Up Stairs',
('Desert Beamos Hall NE', 'Desert Tiles 2 SE'),
('Desert Tiles 2 NE', 'Desert Wall Slide SE'),
],
'Tower of Hera': [
'Hera Lobby Key Stairs'
],
'Agahnims Tower': [
'Tower Room 03 Up Stairs',
('Tower Dark Maze ES', 'Tower Dark Chargers WS'),
'Tower Dark Archers Up Stairs',
('Tower Circle of Pots WS', 'Tower Pacifist Run ES'),
],
'Palace of Darkness': [
('PoD Middle Cage N', 'PoD Pit Room S'),
('PoD Arena Main NW', 'PoD Falling Bridge SW'),
('PoD Falling Bridge WN', 'PoD Dark Maze EN'),
'PoD Basement Ledge Up Stairs',
('PoD Compass Room SE', 'PoD Harmless Hellway NE'),
('PoD Dark Pegs WN', 'PoD Lonely Turtle EN')
],
'Swamp Palace': [
'Swamp Entrance Down Stairs',
('Swamp Pot Row WS', 'Swamp Trench 1 Approach ES'),
('Swamp Trench 1 Key Ledge NW', 'Swamp Hammer Switch SW'),
('Swamp Hub WN', 'Swamp Crystal Switch EN'),
('Swamp Hub North Ledge N', 'Swamp Push Statue S'),
('Swamp Waterway NW', 'Swamp T SW')
],
'Skull Woods': [
('Skull 1 Lobby WS', 'Skull Pot Prison ES'),
('Skull Map Room SE', 'Skull Pinball NE'),
('Skull 2 West Lobby NW', 'Skull X Room SW'),
('Skull 3 Lobby NW', 'Skull Star Pits SW'),
('Skull Spike Corner WS', 'Skull Final Drop ES')
],
'Thieves Town': [
('Thieves Hallway WS', 'Thieves Pot Alcove Mid ES'),
'Thieves Spike Switch Up Stairs',
('Thieves Conveyor Bridge WS', 'Thieves Big Chest Room ES')
],
'Ice Palace': [
'Ice Jelly Key Down Stairs',
('Ice Conveyor SW', 'Ice Bomb Jump NW'),
('Ice Spike Cross ES', 'Ice Spike Room WS'),
('Ice Tall Hint SE', 'Ice Lonely Freezor NE'),
'Ice Backwards Room Down Stairs',
('Ice Switch Room ES', 'Ice Refill WS')
],
'Misery Mire': [
('Mire Hub WS', 'Mire Conveyor Crystal ES'),
('Mire Hub Right EN', 'Mire Map Spot WN'),
('Mire Spikes NW', 'Mire Ledgehop SW'),
('Mire Fishbone SE', 'Mire Spike Barrier NE'),
('Mire Conveyor Crystal WS', 'Mire Tile Room ES'),
('Mire Dark Shooters SE', 'Mire Key Rupees NE')
],
'Turtle Rock': [
('TR Hub NW', 'TR Pokey 1 SW'),
('TR Pokey 1 NW', 'TR Chain Chomps SW'),
'TR Chain Chomps Down Stairs',
('TR Pokey 2 ES', 'TR Lava Island WS'),
'TR Crystaroller Down Stairs',
('TR Dash Bridge WS', 'TR Crystal Maze ES')
],
'Ganons Tower': [
('GT Torch EN', 'GT Hope Room WN'),
('GT Tile Room EN', 'GT Speed Torch WN'),
('GT Hookshot ES', 'GT Map Room WS'),
('GT Double Switch EN', 'GT Spike Crystals WN'),
('GT Firesnake Room SW', 'GT Warp Maze (Rails) NW'),
('GT Conveyor Star Pits EN', 'GT Falling Bridge WN'),
('GT Mini Helmasaur Room WN', 'GT Bomb Conveyor EN'),
('GT Crystal Circles SW', 'GT Left Moldorm Ledge NW')
]
}
default_door_connections = [
('Hyrule Castle Lobby W', 'Hyrule Castle West Lobby E'),
('Hyrule Castle Lobby E', 'Hyrule Castle East Lobby W'),
@@ -1791,7 +2017,7 @@ default_door_connections = [
('Mire Minibridge NE', 'Mire Right Bridge SE'),
('Mire BK Door Room EN', 'Mire Ledgehop WN'),
('Mire BK Door Room N', 'Mire Left Bridge S'),
('Mire Spikes SW', 'Mire Crystal Dead End NE'),
('Mire Spikes SW', 'Mire Crystal Dead End NW'),
('Mire Ledgehop NW', 'Mire Bent Bridge SW'),
('Mire Bent Bridge W', 'Mire Over Bridge E'),
('Mire Over Bridge W', 'Mire Fishbone E'),
@@ -1819,10 +2045,27 @@ default_door_connections = [
('TR Dark Ride SW', 'TR Dash Bridge NW'),
('TR Dash Bridge SW', 'TR Eye Bridge NW'),
('TR Dash Bridge WS', 'TR Crystal Maze ES'),
# ('', ''),
('GT Torch WN', 'GT Conveyor Cross EN'),
('GT Hope Room EN', 'GT Tile Room WN'),
('GT Big Chest SW', 'GT Invisible Catwalk NW'),
('GT Bob\'s Room SE', 'GT Invisible Catwalk NE'),
('GT Speed Torch NE', 'GT Trap Room SE'),
('GT Speed Torch SE', 'GT Crystal Conveyor NE'),
('GT Warp Maze (Pits) ES', 'GT Invisible Catwalk WS'),
('GT Hookshot NW', 'GT DMs Room SW'),
('GT Hookshot SW', 'GT Double Switch NW'),
('GT Warp Maze (Rails) WS', 'GT Randomizer Room ES'),
('GT Conveyor Star Pits EN', 'GT Falling Bridge WN'),
('GT Falling Bridge WS', 'GT Hidden Star ES'),
('GT Dash Hall NE', 'GT Hidden Spikes SE'),
('GT Hidden Spikes EN', 'GT Cannonball Bridge WN'),
('GT Gauntlet 3 SW', 'GT Gauntlet 4 NW'),
('GT Gauntlet 5 WS', 'GT Beam Dash ES'),
('GT Wizzrobes 2 NE', 'GT Conveyor Bridge SE'),
('GT Conveyor Bridge EN', 'GT Torch Cross WN'),
('GT Crystal Circles SW', 'GT Left Moldorm Ledge NW')
]
# ('', ''),
default_one_way_connections = [
('Sewers Pull Switch S', 'Sanctuary N'),
('Eastern Duo Eyegores NE', 'Eastern Boss SE'),
@@ -1834,7 +2077,9 @@ default_one_way_connections = [
('Thieves Hallway NE', 'Thieves Boss SE'),
('Mire Antechamber NW', 'Mire Boss SW'),
('TR Final Abyss NW', 'TR Boss SW'),
# ('', ''),
('GT Invisible Bridges WS', 'GT Invisible Catwalk ES'),
('GT Validation WS', 'GT Frozen Over ES'),
('GT Brightly Lit Hall NW', 'GT Agahnim 2 SW')
]
# For crossed
@@ -1852,7 +2097,8 @@ default_dungeon_sets = [
['Thieves Lobby', 'Thieves Attic Window', 'Thieves Blind\'s Cell', 'Thieves Boss'],
['Ice Lobby', 'Ice Boss'],
['Mire Lobby', 'Mire Boss'],
['TR Main Lobby', 'TR Boss', 'TR Eye Bridge', 'TR Big Chest Entrance', 'TR Lazy Eyes']
['TR Main Lobby', 'TR Boss', 'TR Eye Bridge', 'TR Big Chest Entrance', 'TR Lazy Eyes'],
['GT Lobby', 'GT Agahnim 2']
]
dungeon_x_idx_to_name = {
@@ -1868,5 +2114,5 @@ dungeon_x_idx_to_name = {
9: 'Ice Palace',
10: 'Misery Mire',
11: 'Turtle Rock',
12: 'Ganon\'s Tower'
12: 'Ganons Tower'
}

204
Doors.py
View File

@@ -431,7 +431,7 @@ def create_doors(world, player):
create_door(player, 'Swamp Big Key Ledge WN', Nrml).dir(We, 0x35, Top, High).pos(1),
create_door(player, 'Swamp West Shallows ES', Nrml).dir(Ea, 0x34, Bot, High).pos(1),
create_door(player, 'Swamp West Shallows Push Blocks', Lgcl),
create_door(player, 'Swamp West Block Path Up Stairs', Sprl).dir(Up, 0x34, 0, HTH).ss(Z, 0x1b, 0x6c, False, True),
create_door(player, 'Swamp West Block Path Up Stairs', Sprl).dir(Up, 0x34, 0, HTH).ss(Z, 0x1b, 0x6c),
create_door(player, 'Swamp West Block Path Drop Down', Lgcl),
create_door(player, 'Swamp West Ledge Drop Down', Lgcl),
create_door(player, 'Swamp West Ledge Hook Path', Lgcl),
@@ -440,7 +440,7 @@ def create_doors(world, player):
create_door(player, 'Swamp Barrier EN', Nrml).dir(Ea, 0x34, Top, High).pos(0),
create_door(player, 'Swamp Barrier - Orange', Lgcl),
create_door(player, 'Swamp Barrier Ledge Hook Path', Lgcl),
create_door(player, 'Swamp Attic Down Stairs', Sprl).dir(Dn, 0x54, 0, HTH).ss(Z, 0x12, 0x80, False, True),
create_door(player, 'Swamp Attic Down Stairs', Sprl).dir(Dn, 0x54, 0, HTH).ss(Z, 0x12, 0x80),
create_door(player, 'Swamp Attic Left Pit', Hole),
create_door(player, 'Swamp Attic Right Pit', Hole),
create_door(player, 'Swamp Push Statue S', Nrml).dir(So, 0x26, Mid, High).small_key().pos(0),
@@ -721,7 +721,7 @@ def create_doors(world, player):
create_door(player, 'Mire Falling Bridge WN', Intr).dir(We, 0xc3, Top, High).pos(1),
create_door(player, 'Mire Map Spike Side EN', Intr).dir(Ea, 0xc3, Top, High).no_exit().pos(1),
create_door(player, 'Mire Map Spot WN', Nrml).dir(We, 0xc3, Top, High).small_key().pos(0),
create_door(player, 'Mire Crystal Dead End NE', Nrml).dir(No, 0xc3, Right, High).pos(4),
create_door(player, 'Mire Crystal Dead End NW', Nrml).dir(No, 0xc3, Left, High).pos(4),
create_door(player, 'Mire Map Spike Side Drop Down', Lgcl),
create_door(player, 'Mire Map Spike Side Blue Barrier', Lgcl),
create_door(player, 'Mire Map Spot Blue Barrier', Lgcl),
@@ -883,13 +883,165 @@ def create_doors(world, player):
create_door(player, 'TR Final Abyss NW', Nrml).dir(No, 0xb4, Left, High).big_key().pos(0),
create_door(player, 'TR Boss SW', Nrml).dir(So, 0xa4, Left, High).no_exit().trap(0x4).pos(0),
# Door Templates
# create_door(player, '', Nrml).dir(No, 0x00, Right, High).pos(),
# create_door(player, '', Intr).dir(No, 0x00, Right, High).pos(),
# create_door(player, '', Sprl).dir(Up, 0x00, 0, HTH).ss(Q, 0x0, 0x0),
# create_door(player, '', Lgcl),
# create_door(player, '', Hole),
# create_door(player, '', Warp),
create_door(player, 'GT Lobby Left Down Stairs', Sprl).dir(Dn, 0x0c, 1, HTL).ss(A, 0x0f, 0x80),
create_door(player, 'GT Lobby Up Stairs', Sprl).dir(Up, 0x0c, 2, HTH).ss(A, 0x1b, 0xec),
create_door(player, 'GT Lobby Right Down Stairs', Sprl).dir(Dn, 0x0c, 0, HTL).ss(S, 0x12, 0x80),
create_door(player, 'GT Torch Up Stairs', Sprl).dir(Up, 0x8c, 1, LTH).ss(A, 0x33, 0x6c, True, True),
create_door(player, 'GT Torch WN', Nrml).dir(We, 0x8c, Top, High).pos(3),
create_door(player, 'GT Hope Room Up Stairs', Sprl).dir(Up, 0x8c, 0, LTH).ss(S, 0x33, 0x6c, True, True),
create_door(player, 'GT Hope Room EN', Nrml).dir(Ea, 0x8c, Top, High).trap(0x4).pos(0),
create_door(player, 'GT Torch EN', Intr).dir(Ea, 0x8c, Top, High).small_key().pos(2),
create_door(player, 'GT Hope Room WN', Intr).dir(We, 0x8c, Top, High).small_key().pos(2),
create_door(player, 'GT Torch SW', Intr).dir(So, 0x8c, Left, High).no_exit().pos(1),
create_door(player, 'GT Big Chest NW', Intr).dir(So, 0x8c, Left, High).pos(1),
create_door(player, 'GT Blocked Stairs Down Stairs', Sprl).dir(Dn, 0x8c, 3, HTH).ss(Z, 0x12, 0x40, True, True),
create_door(player, 'GT Blocked Stairs Block Path', Lgcl),
create_door(player, 'GT Big Chest SW', Nrml).dir(So, 0x8c, Left, High).pos(4),
create_door(player, 'GT Bob\'s Room SE', Nrml).dir(So, 0x8c, Right, High).pos(5),
create_door(player, 'GT Bob\'s Room Hole', Hole),
create_door(player, 'GT Tile Room WN', Nrml).dir(We, 0x8d, Top, High).pos(2),
create_door(player, 'GT Tile Room EN', Intr).dir(Ea, 0x8d, Top, High).small_key().pos(1),
create_door(player, 'GT Speed Torch WN', Intr).dir(We, 0x8d, Top, High).small_key().pos(1),
create_door(player, 'GT Speed Torch NE', Nrml).dir(No, 0x8d, Right, High).pos(3),
create_door(player, 'GT Speed Torch WS', Intr).dir(We, 0x8d, Bot, High).pos(4),
create_door(player, 'GT Pots n Blocks ES', Intr).dir(Ea, 0x8d, Bot, High).pos(4),
create_door(player, 'GT Speed Torch SE', Nrml).dir(So, 0x8d, Right, High).trap(0x4).pos(0),
create_door(player, 'GT Crystal Conveyor NE', Nrml).dir(No, 0x9d, Right, High).pos(0),
create_door(player, 'GT Crystal Conveyor WN', Intr).dir(We, 0x9d, Top, High).pos(2),
create_door(player, 'GT Compass Room EN', Intr).dir(Ea, 0x9d, Top, High).pos(2),
create_door(player, 'GT Compass Room Warp', Warp),
create_door(player, 'GT Invisible Bridges WS', Nrml).dir(We, 0x9d, Bot, High).pos(1),
create_door(player, 'GT Invisible Catwalk ES', Nrml).dir(Ea, 0x9c, Bot, High).no_exit().pos(0),
create_door(player, 'GT Invisible Catwalk WS', Nrml).dir(We, 0x9c, Bot, High).pos(3),
create_door(player, 'GT Invisible Catwalk NW', Nrml).dir(No, 0x9c, Left, High).pos(1),
create_door(player, 'GT Invisible Catwalk NE', Nrml).dir(No, 0x9c, Right, High).pos(2),
create_door(player, 'GT Conveyor Cross EN', Nrml).dir(Ea, 0x8b, Top, High).pos(2),
create_door(player, 'GT Conveyor Cross WN', Intr).dir(We, 0x8b, Top, High).pos(0),
create_door(player, 'GT Hookshot EN', Intr).dir(Ea, 0x8b, Top, High).pos(0),
create_door(player, 'GT Hookshot East-North Path', Lgcl),
create_door(player, 'GT Hookshot East-South Path', Lgcl),
create_door(player, 'GT Hookshot North-East Path', Lgcl),
create_door(player, 'GT Hookshot North-South Path', Lgcl),
create_door(player, 'GT Hookshot South-East Path', Lgcl),
create_door(player, 'GT Hookshot South-North Path', Lgcl),
create_door(player, 'GT Hookshot Platform Blue Barrier', Lgcl),
create_door(player, 'GT Hookshot Entry Blue Barrier', Lgcl),
create_door(player, 'GT Hookshot NW', Nrml).dir(No, 0x8b, Left, High).pos(4),
create_door(player, 'GT Hookshot ES', Intr).dir(Ea, 0x8b, Bot, High).small_key().pos(1),
create_door(player, 'GT Map Room WS', Intr).dir(We, 0x8b, Bot, High).small_key().pos(1),
create_door(player, 'GT Hookshot SW', Nrml).dir(So, 0x8b, Left, High).pos(3),
create_door(player, 'GT Double Switch NW', Nrml).dir(No, 0x9b, Left, High).pos(1),
create_door(player, 'GT Double Switch Orange Barrier', Lgcl),
create_door(player, 'GT Double Switch Orange Barrier 2', Lgcl),
create_door(player, 'GT Double Switch Blue Path', Lgcl),
create_door(player, 'GT Double Switch Orange Path', Lgcl),
create_door(player, 'GT Double Switch Key Blue Path', Lgcl),
create_door(player, 'GT Double Switch Key Orange Path', Lgcl),
create_door(player, 'GT Double Switch Blue Barrier', Lgcl),
create_door(player, 'GT Double Switch Transition Blue', Lgcl),
create_door(player, 'GT Double Switch EN', Intr).dir(Ea, 0x9b, Top, High).small_key().pos(0),
create_door(player, 'GT Spike Crystals WN', Intr).dir(We, 0x9b, Top, High).small_key().pos(0),
create_door(player, 'GT Spike Crystals Warp', Warp),
create_door(player, 'GT Warp Maze - Left Section Warp', Warp),
create_door(player, 'GT Warp Maze - Mid Section Left Warp', Warp),
create_door(player, 'GT Warp Maze - Mid Section Right Warp', Warp),
create_door(player, 'GT Warp Maze - Right Section Warp', Warp),
create_door(player, 'GT Warp Maze - Pit Section Warp Spot', Lgcl),
create_door(player, 'GT Warp Maze Exit Section Warp Spot', Lgcl),
create_door(player, 'GT Warp Maze - Pit Exit Warp', Warp),
create_door(player, 'GT Warp Maze (Pits) ES', Nrml).dir(Ea, 0x9b, Bot, High).pos(2),
create_door(player, 'GT Firesnake Room Hook Path', Lgcl),
create_door(player, 'GT Firesnake Room SW', Intr).dir(So, 0x7d, Left, High).small_key().pos(2),
create_door(player, 'GT Warp Maze (Rails) NW', Intr).dir(No, 0x7d, Left, High).small_key().pos(2),
create_door(player, 'GT Warp Maze - Rail Choice Left Warp', Warp),
create_door(player, 'GT Warp Maze - Rail Choice Right Warp', Warp),
create_door(player, 'GT Warp Maze - Rando Rail Warp', Warp),
create_door(player, 'GT Warp Maze - Main Rails Best Warp', Warp),
create_door(player, 'GT Warp Maze - Main Rails Mid Left Warp', Warp),
create_door(player, 'GT Warp Maze - Main Rails Mid Right Warp', Warp),
create_door(player, 'GT Warp Maze - Main Rails Right Top Warp', Warp),
create_door(player, 'GT Warp Maze - Main Rails Right Mid Warp', Warp),
create_door(player, 'GT Warp Maze - Pot Rail Warp', Warp),
create_door(player, 'GT Warp Maze (Rails) WS', Nrml).dir(We, 0x7d, Bot, High).pos(1),
create_door(player, 'GT Trap Room SE', Nrml).dir(So, 0x7d, Right, High).trap(0x4).pos(0),
create_door(player, 'GT Conveyor Star Pits EN', Nrml).dir(Ea, 0x7b, Top, High).small_key().pos(1),
create_door(player, 'GT Hidden Star ES', Nrml).dir(Ea, 0x7b, Bot, High).pos(2),
create_door(player, 'GT Hidden Star Warp', Warp),
create_door(player, 'GT DMs Room SW', Nrml).dir(So, 0x7b, Left, High).trap(0x4).pos(0),
create_door(player, 'GT Falling Bridge WN', Nrml).dir(We, 0x7c, Top, High).small_key().pos(2),
create_door(player, 'GT Falling Bridge WS', Nrml).dir(We, 0x7c, Bot, High).pos(3),
create_door(player, 'GT Randomizer Room ES', Nrml).dir(Ea, 0x7c, Bot, High).pos(1),
create_door(player, 'GT Ice Armos NE', Intr).dir(No, 0x1c, Right, High).pos(0),
create_door(player, 'GT Big Key Room SE', Intr).dir(So, 0x1c, Right, High).pos(0),
create_door(player, 'GT Ice Armos WS', Intr).dir(We, 0x1c, Bot, High).pos(1),
create_door(player, 'GT Four Torches ES', Intr).dir(Ea, 0x1c, Bot, High).pos(1),
create_door(player, 'GT Four Torches NW', Intr).dir(No, 0x1c, Left, High).pos(2),
create_door(player, 'GT Fairy Abyss SW', Intr).dir(So, 0x1c, Left, High).pos(2),
create_door(player, 'GT Four Torches Up Stairs', Sprl).dir(Up, 0x1c, 0, HTH).ss(Z, 0x1b, 0x2c, True, True),
create_door(player, 'GT Crystal Paths Down Stairs', Sprl).dir(Dn, 0x6b, 0, HTH).ss(A, 0x12, 0x00, True),
create_door(player, 'GT Crystal Paths SW', Intr).dir(So, 0x6b, Left, High).pos(3),
create_door(player, 'GT Mimics 1 NW', Intr).dir(No, 0x6b, Left, High).pos(3),
create_door(player, 'GT Mimics 1 ES', Intr).dir(Ea, 0x6b, Bot, High).pos(2),
create_door(player, 'GT Mimics 2 WS', Intr).dir(We, 0x6b, Bot, High).pos(2),
create_door(player, 'GT Mimics 2 NE', Intr).dir(No, 0x6b, Right, High).pos(1),
create_door(player, 'GT Dash Hall SE', Intr).dir(So, 0x6b, Right, High).pos(1),
create_door(player, 'GT Dash Hall NE', Nrml).dir(No, 0x6b, Right, High).big_key().pos(0),
create_door(player, 'GT Hidden Spikes SE', Nrml).dir(So, 0x5b, Right, High).small_key().pos(0),
create_door(player, 'GT Hidden Spikes EN', Nrml).dir(Ea, 0x5b, Top, High).trap(0x2).pos(1),
create_door(player, 'GT Cannonball Bridge WN', Nrml).dir(We, 0x5c, Top, High).pos(1),
create_door(player, 'GT Cannonball Bridge SE', Intr).dir(So, 0x5c, Right, High).pos(0),
create_door(player, 'GT Refill NE', Intr).dir(No, 0x5c, Right, High).pos(0),
create_door(player, 'GT Cannonball Bridge Up Stairs', Sprl).dir(Up, 0x5c, 0, HTH).ss(S, 0x1a, 0x6c, True),
create_door(player, 'GT Gauntlet 1 Down Stairs', Sprl).dir(Dn, 0x5d, 0, HTH).ss(S, 0x11, 0x80, True, True),
create_door(player, 'GT Gauntlet 1 WN', Intr).dir(We, 0x5d, Top, High).pos(2),
create_door(player, 'GT Gauntlet 2 EN', Intr).dir(Ea, 0x5d, Top, High).pos(2),
create_door(player, 'GT Gauntlet 2 SW', Intr).dir(So, 0x5d, Left, High).pos(0),
create_door(player, 'GT Gauntlet 3 NW', Intr).dir(No, 0x5d, Left, High).pos(0),
create_door(player, 'GT Gauntlet 3 SW', Nrml).dir(So, 0x5d, Left, High).pos(1),
create_door(player, 'GT Gauntlet 4 NW', Nrml).dir(No, 0x6d, Left, High).pos(0),
create_door(player, 'GT Gauntlet 4 SW', Intr).dir(So, 0x6d, Left, High).pos(1),
create_door(player, 'GT Gauntlet 5 NW', Intr).dir(No, 0x6d, Left, High).pos(1),
create_door(player, 'GT Gauntlet 5 WS', Nrml).dir(We, 0x6d, Bot, High).pos(2),
create_door(player, 'GT Beam Dash ES', Nrml).dir(Ea, 0x6c, Bot, High).pos(2),
create_door(player, 'GT Beam Dash WS', Intr).dir(We, 0x6c, Bot, High).pos(0),
create_door(player, 'GT Lanmolas 2 ES', Intr).dir(Ea, 0x6c, Bot, High).pos(0),
create_door(player, 'GT Lanmolas 2 NW', Intr).dir(No, 0x6c, Left, High).pos(1),
create_door(player, 'GT Quad Pot SW', Intr).dir(So, 0x6c, Left, High).pos(1),
create_door(player, 'GT Quad Pot Up Stairs', Sprl).dir(Up, 0x6c, 0, HTH).ss(A, 0x1b, 0x6c, True, True),
create_door(player, 'GT Wizzrobes 1 Down Stairs', Sprl).dir(Dn, 0xa5, 0, HTH).ss(A, 0x12, 0x80, True, True),
create_door(player, 'GT Wizzrobes 1 SW', Intr).dir(So, 0xa5, Left, High).pos(2),
create_door(player, 'GT Dashing Bridge NW', Intr).dir(No, 0xa5, Left, High).pos(2),
create_door(player, 'GT Dashing Bridge NE', Intr).dir(No, 0xa5, Right, High).pos(1),
create_door(player, 'GT Wizzrobes 2 SE', Intr).dir(So, 0xa5, Right, High).pos(1),
create_door(player, 'GT Wizzrobes 2 NE', Nrml).dir(No, 0xa5, Right, High).trap(0x4).pos(0),
create_door(player, 'GT Conveyor Bridge SE', Nrml).dir(So, 0x95, Right, High).pos(0),
create_door(player, 'GT Conveyor Bridge EN', Nrml).dir(Ea, 0x95, Top, High).pos(1),
create_door(player, 'GT Torch Cross WN', Nrml).dir(We, 0x96, Top, High).pos(1),
create_door(player, 'GT Torch Cross ES', Intr).dir(Ea, 0x96, Bot, High).pos(0),
create_door(player, 'GT Staredown WS', Intr).dir(We, 0x96, Bot, High).pos(0),
create_door(player, 'GT Staredown Up Ladder', Lddr),
create_door(player, 'GT Falling Torches Down Ladder', Lddr),
create_door(player, 'GT Falling Torches NE', Intr).dir(No, 0x3d, Right, High).pos(0),
create_door(player, 'GT Mini Helmasaur Room SE', Intr).dir(So, 0x3d, Right, High).pos(0),
create_door(player, 'GT Falling Torches Hole', Hole),
create_door(player, 'GT Mini Helmasaur Room WN', Intr).dir(We, 0x3d, Top, High).small_key().pos(1),
create_door(player, 'GT Bomb Conveyor EN', Intr).dir(Ea, 0x3d, Top, High).small_key().pos(1),
create_door(player, 'GT Bomb Conveyor SW', Intr).dir(So, 0x3d, Left, High).pos(3),
create_door(player, 'GT Crystal Circles NW', Intr).dir(No, 0x3d, Left, High).pos(3),
create_door(player, 'GT Crystal Circles SW', Nrml).dir(So, 0x3d, Left, High).small_key().pos(2),
create_door(player, 'GT Left Moldorm Ledge NW', Nrml).dir(No, 0x4d, Left, High).small_key().pos(0),
create_door(player, 'GT Left Moldorm Ledge Drop Down', Lgcl),
create_door(player, 'GT Right Moldorm Ledge Drop Down', Lgcl),
create_door(player, 'GT Moldorm Gap', Lgcl),
create_door(player, 'GT Moldorm Hole', Hole),
create_door(player, 'GT Validation WS', Nrml).dir(We, 0x4d, Bot, High).pos(1),
create_door(player, 'GT Right Moldorm Ledge Down Stairs', Sprl).dir(Dn, 0x4d, 0, HTH).ss(S, 0x12, 0x80),
create_door(player, 'GT Moldorm Pit Up Stairs', Sprl).dir(Up, 0xa6, 0, HTH).ss(S, 0x1b, 0x6c),
create_door(player, 'GT Frozen Over ES', Nrml).dir(Ea, 0x4c, Bot, High).trap(0x4).pos(0),
create_door(player, 'GT Frozen Over Up Stairs', Sprl).dir(Up, 0x4c, 0, HTH).ss(S, 0x1a, 0x6c, False, True),
create_door(player, 'GT Brightly Lit Hall Down Stairs', Sprl).dir(Dn, 0x1d, 0, HTH).ss(S, 0x11, 0x80, False, True),
create_door(player, 'GT Brightly Lit Hall NW', Nrml).dir(No, 0x1d, Left, High).big_key().pos(0),
create_door(player, 'GT Agahnim 2 SW', Nrml).dir(So, 0x0d, Left, High).no_exit().trap(0x4).pos(0)
]
create_paired_doors(world, player)
@@ -1004,6 +1156,30 @@ def create_doors(world, player):
world.get_door('TR Crystal Maze ES', player).c_switch()
world.get_door('TR Crystal Maze North Stairs', player).c_switch()
world.get_door('GT Crystal Conveyor NE', player).c_switch()
world.get_door('GT Crystal Conveyor WN', player).c_switch()
world.get_door('GT Hookshot South-North Path', player).c_switch()
world.get_door('GT Hookshot South-East Path', player).c_switch()
world.get_door('GT Hookshot ES', player).c_switch()
world.get_door('GT Hookshot Platform Blue Barrier', player).c_switch()
world.get_door('GT Double Switch Orange Path', player).c_switch()
world.get_door('GT Double Switch Blue Path', player).c_switch()
world.get_door('GT Spike Crystals WN', player).c_switch()
world.get_door('GT Spike Crystals Warp', player).c_switch()
world.get_door('GT Crystal Paths Down Stairs', player).c_switch()
world.get_door('GT Crystal Paths SW', player).c_switch()
world.get_door('GT Hidden Spikes SE', player).c_switch()
world.get_door('GT Hidden Spikes EN', player).c_switch()
world.get_door('GT Crystal Circles NW', player).c_switch()
world.get_door('GT Crystal Circles SW', player).c_switch()
world.get_door('GT Hookshot Entry Blue Barrier', player).barrier(CrystalBarrier.Blue)
world.get_door('GT Double Switch Orange Barrier', player).barrier(CrystalBarrier.Orange)
world.get_door('GT Double Switch Orange Barrier 2', player).barrier(CrystalBarrier.Orange)
world.get_door('GT Double Switch Key Orange Path', player).barrier(CrystalBarrier.Orange)
world.get_door('GT Double Switch Key Blue Path', player).barrier(CrystalBarrier.Blue)
world.get_door('GT Double Switch Blue Barrier', player).barrier(CrystalBarrier.Blue)
world.get_door('GT Double Switch Transition Blue', player).barrier(CrystalBarrier.Blue)
# nifty dynamic logical doors:
south_controller = world.get_door('Ice Cross Bottom SE', player)
east_controller = world.get_door('Ice Cross Right ES', player)
@@ -1029,16 +1205,16 @@ def create_paired_doors(world, player):
PairedDoor('Swamp Pot Row WN', 'Swamp Map Ledge EN'), # Swamp bombable to map chest
PairedDoor('Swamp Pot Row WS', 'Swamp Trench 1 Approach ES'), # Swamp key door early room $38
PairedDoor('PoD Middle Cage N', 'PoD Pit Room S'),
# PairedDoor('', ''), # GT moldorm key door
PairedDoor('GT Crystal Circles SW', 'GT Left Moldorm Ledge NW'), # GT moldorm key door
PairedDoor('Ice Conveyor SW', 'Ice Bomb Jump NW'), # Ice BJ key door
PairedDoor('Desert Tiles 2 SE', 'Desert Beamos Hall NE'),
PairedDoor('Skull 3 Lobby NW', 'Skull Star Pits SW'), # Skull 3 key door
PairedDoor('Skull 1 Lobby WS', 'Skull Pot Prison ES'), # Skull 1 key door - pot prison to big chest
PairedDoor('Skull Map Room SE', 'Skull Pinball NE'), # Skull 1 - pinball key door
# PairedDoor('', ''), # gt main big key door
PairedDoor('GT Dash Hall NE', 'GT Hidden Spikes SE'), # gt main big key door
PairedDoor('Ice Spike Cross ES', 'Ice Spike Room WS'), # ice door to spike chest
# PairedDoor('', ''), # gt right side key door to cape bridge
# PairedDoor('', ''), # gt bombable to rando room
PairedDoor('GT Conveyor Star Pits EN', 'GT Falling Bridge WN'), # gt right side key door to cape bridge
PairedDoor('GT Warp Maze (Rails) WS', 'GT Randomizer Room ES'), # gt bombable to rando room
PairedDoor('Ice Tall Hint SE', 'Ice Lonely Freezor NE'), # ice's big icy room key door to lonely freezor
PairedDoor('Eastern Courtyard N', 'Eastern Darkness S'),
PairedDoor('Mire Fishbone SE', 'Mire Spike Barrier NE'), # mire fishbone key door

View File

@@ -75,6 +75,8 @@ def generate_dungeon(available_sectors, entrance_region_names, world, player):
choices_master.pop()
dungeon_cache.pop(depth, None)
depth -= 1
if depth < 0:
raise Exception('Invalid dungeon. Ref %s' % entrance_region_names[0])
a, b = choices_master[depth][-1]
logger.debug(' '*depth+"%d: Rescinding %s, %s", depth, a.name, b.name)
proposed_map.pop(a, None)
@@ -289,7 +291,8 @@ def winnow_hangers(hangers, hooks):
found_valid = False
for door_hook, crystal, orig_hanger in hook_set:
if orig_hanger != door:
found_valid = True # todo: break
found_valid = True
break
if not found_valid:
removal_info.append((hanger, door))
for hanger, door in removal_info:
@@ -746,7 +749,7 @@ def extend_reachable_state_improved(search_regions, state, proposed_map, valid_d
# cross-utility methods
def valid_region_to_explore(region, world):
return region.type == RegionType.Dungeon or region.name in world.inaccessible_regions
return region is not None and (region.type == RegionType.Dungeon or region.name in world.inaccessible_regions)
def get_doors(world, region, player):

View File

@@ -21,7 +21,7 @@ def create_dungeons(world, player):
ToH = make_dungeon('Tower of Hera', 'Moldorm', hera_regions, ItemFactory('Big Key (Tower of Hera)', player), [ItemFactory('Small Key (Tower of Hera)', player)], ItemFactory(['Map (Tower of Hera)', 'Compass (Tower of Hera)'], player))
PoD = make_dungeon('Palace of Darkness', 'Helmasaur King', pod_regions, ItemFactory('Big Key (Palace of Darkness)', player), ItemFactory(['Small Key (Palace of Darkness)'] * 6, player), ItemFactory(['Map (Palace of Darkness)', 'Compass (Palace of Darkness)'], player))
TT = make_dungeon('Thieves Town', 'Blind', thieves_regions, ItemFactory('Big Key (Thieves Town)', player), [ItemFactory('Small Key (Thieves Town)', player)], ItemFactory(['Map (Thieves Town)', 'Compass (Thieves Town)'], player))
SW = make_dungeon('Skull Woods', 'Mothula', skull_regions, ItemFactory('Big Key (Skull Woods)', player), ItemFactory(['Small Key (Skull Woods)'] * 2, player), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)'], player))
SW = make_dungeon('Skull Woods', 'Mothula', skull_regions, ItemFactory('Big Key (Skull Woods)', player), ItemFactory(['Small Key (Skull Woods)'] * 3, player), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)'], player))
SP = make_dungeon('Swamp Palace', 'Arrghus', swamp_regions, ItemFactory('Big Key (Swamp Palace)', player), [ItemFactory('Small Key (Swamp Palace)', player)], ItemFactory(['Map (Swamp Palace)', 'Compass (Swamp Palace)'], player))
IP = make_dungeon('Ice Palace', 'Kholdstare', ice_regions, ItemFactory('Big Key (Ice Palace)', player), ItemFactory(['Small Key (Ice Palace)'] * 2, player), ItemFactory(['Map (Ice Palace)', 'Compass (Ice Palace)'], player))
MM = make_dungeon('Misery Mire', 'Vitreous', mire_regions, ItemFactory('Big Key (Misery Mire)', player), ItemFactory(['Small Key (Misery Mire)'] * 3, player), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)'], player))
@@ -29,7 +29,7 @@ def create_dungeons(world, player):
if world.mode != 'inverted':
AT = make_dungeon('Agahnims Tower', 'Agahnim', tower_regions, None, ItemFactory(['Small Key (Agahnims Tower)'] * 2, player), [])
GT = make_dungeon('Ganons Tower', 'Agahnim2', ['Ganons Tower (Entrance)', 'Ganons Tower (Tile Room)', 'Ganons Tower (Compass Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower (Map Room)', 'Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)', 'Ganons Tower (Bottom)', 'Ganons Tower (Top)', 'Ganons Tower (Before Moldorm)', 'Ganons Tower (Moldorm)', 'Agahnim 2'], ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
GT = make_dungeon('Ganons Tower', 'Agahnim2', gt_regions, ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
else:
AT = make_dungeon('Inverted Agahnims Tower', 'Agahnim', ['Inverted Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2, player), [])
GT = make_dungeon('Inverted Ganons Tower', 'Agahnim2', ['Inverted Ganons Tower (Entrance)', 'Ganons Tower (Tile Room)', 'Ganons Tower (Compass Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower (Map Room)', 'Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)', 'Ganons Tower (Bottom)', 'Ganons Tower (Top)', 'Ganons Tower (Before Moldorm)', 'Ganons Tower (Moldorm)', 'Agahnim 2'], ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
@@ -125,15 +125,15 @@ def get_dungeon_item_pool(world):
def fill_dungeons_restrictive(world, shuffled_locations):
all_state_base = world.get_all_state()
for player in range(1, world.players + 1):
pinball_room = world.get_location('Skull Woods - Pinball Room', player)
if world.retro:
world.push_item(pinball_room, ItemFactory('Small Key (Universal)', player), False)
else:
world.push_item(pinball_room, ItemFactory('Small Key (Skull Woods)', player), False)
pinball_room.event = True
pinball_room.locked = True
shuffled_locations.remove(pinball_room)
# for player in range(1, world.players + 1):
# pinball_room = world.get_location('Skull Woods - Pinball Room', player)
# if world.retro:
# world.push_item(pinball_room, ItemFactory('Small Key (Universal)', player), False)
# else:
# world.push_item(pinball_room, ItemFactory('Small Key (Skull Woods)', player), False)
# pinball_room.event = True
# pinball_room.locked = True
# shuffled_locations.remove(pinball_room)
if world.keysanity:
#in keysanity dungeon items are distributed as part of the normal item pool
@@ -277,6 +277,27 @@ tr_regions = [
'TR Crystaroller', 'TR Dark Ride', 'TR Dash Bridge', 'TR Eye Bridge', 'TR Crystal Maze', 'TR Final Abyss', 'TR Boss'
]
gt_regions = [
'GT Lobby', 'GT Bob\'s Torch', 'GT Hope Room', 'GT Big Chest', 'GT Blocked Stairs', 'GT Bob\'s Room',
'GT Tile Room', 'GT Speed Torch', 'GT Pots n Blocks', 'GT Crystal Conveyor', 'GT Compass Room',
'GT Invisible Bridges', 'GT Invisible Catwalk', 'GT Conveyor Cross', 'GT Hookshot East Platform',
'GT Hookshot North Platform', 'GT Hookshot South Platform', 'GT Hookshot South Entry', 'GT Map Room',
'GT Double Switch Entry', 'GT Double Switch Switches', 'GT Double Switch Transition', 'GT Double Switch Key Spot',
'GT Double Switch Exit', 'GT Spike Crystals', 'GT Warp Maze - Left Section', 'GT Warp Maze - Mid Section',
'GT Warp Maze - Right Section', 'GT Warp Maze - Pit Section', 'GT Warp Maze - Pit Exit Warp Spot',
'GT Warp Maze Exit Section', 'GT Firesnake Room', 'GT Firesnake Room Ledge', 'GT Warp Maze - Rail Choice',
'GT Warp Maze - Rando Rail', 'GT Warp Maze - Main Rails', 'GT Warp Maze - Pot Rail', 'GT Trap Room',
'GT Conveyor Star Pits', 'GT Hidden Star', 'GT DMs Room', 'GT Falling Bridge', 'GT Randomizer Room', 'GT Ice Armos',
'GT Big Key Room', 'GT Four Torches', 'GT Fairy Abyss', 'GT Crystal Paths', 'GT Mimics 1', 'GT Mimics 2',
'GT Dash Hall', 'GT Hidden Spikes', 'GT Cannonball Bridge', 'GT Refill', 'GT Gauntlet 1', 'GT Gauntlet 2',
'GT Gauntlet 3', 'GT Gauntlet 4', 'GT Gauntlet 5', 'GT Beam Dash', 'GT Lanmolas 2', 'GT Quad Pot', 'GT Wizzrobes 1',
'GT Dashing Bridge', 'GT Wizzrobes 2', 'GT Conveyor Bridge', 'GT Torch Cross', 'GT Staredown', 'GT Falling Torches',
'GT Mini Helmasaur Room', 'GT Bomb Conveyor', 'GT Crystal Circles', 'GT Left Moldorm Ledge',
'GT Right Moldorm Ledge', 'GT Moldorm', 'GT Moldorm Pit', 'GT Validation', 'GT Frozen Over', 'GT Brightly Lit Hall',
'GT Agahnim 2'
]
dungeon_regions = {
'Hyrule Castle': hyrule_castle_regions,
'Eastern Palace': eastern_regions,
@@ -290,7 +311,7 @@ dungeon_regions = {
'Ice Palace': ice_regions,
'Misery Mire': mire_regions,
'Turtle Rock': tr_regions,
# 'GT':
'Ganons Tower': gt_regions
}
region_starts = {
@@ -307,7 +328,7 @@ region_starts = {
'Ice Palace': ['Ice Lobby'],
'Misery Mire': ['Mire Lobby'],
'Turtle Rock': ['TR Main Lobby', 'TR Lazy Eyes', 'TR Big Chest Entrance', 'TR Eye Bridge'],
# ['GT Lobby']
'Ganons Tower': ['GT Lobby']
}
split_region_starts = {
@@ -326,6 +347,10 @@ flexible_starts = {
'Skull Woods': ['Skull Left Drop', 'Skull Pinball']
}
drop_entrances = [
'Sewers Rat Path', 'Skull Pinball', 'Skull Left Drop' # Pot circle, Back drop have unique access
]
dungeon_keys = {
'Hyrule Castle': 'Small Key (Escape)',
'Eastern Palace': 'Small Key (Eastern Palace)',
@@ -339,6 +364,7 @@ dungeon_keys = {
'Ice Palace': 'Small Key (Ice Palace)',
'Misery Mire': 'Small Key (Misery Mire)',
'Turtle Rock': 'Small Key (Turtle Rock)',
'Ganons Tower': 'Small Key (Ganons Tower)'
}
dungeon_bigs = {
@@ -354,5 +380,6 @@ dungeon_bigs = {
'Ice Palace': 'Big Key (Ice Palace)',
'Misery Mire': 'Big Key (Misery Mire)',
'Turtle Rock': 'Big Key (Turtle Rock)',
'Ganons Tower': 'Big Key (Ganons Tower)'
}

View File

@@ -1049,7 +1049,7 @@ def link_entrances(world, player):
raise NotImplementedError('Shuffling not supported yet')
# check for swamp palace fix
if world.get_entrance('Dam', player).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Palace (Entrance)':
if world.get_entrance('Dam', player).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Lobby':
world.swamp_patch_required[player] = True
# check for potion shop location
@@ -1061,7 +1061,7 @@ def link_entrances(world, player):
world.ganon_at_pyramid[player] = False
# check for Ganon's Tower location
if world.get_entrance('Ganons Tower', player).connected_region.name != 'Ganons Tower (Entrance)':
if world.get_entrance('Ganons Tower', player).connected_region.name != 'GT Lobby':
world.ganonstower_vanilla[player] = False
def link_inverted_entrances(world, player):
@@ -2946,22 +2946,9 @@ mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central
('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'),
('Cave 45 Mirror Spot', 'Cave 45 Ledge'),
('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'),
('Ganons Tower (Tile Room)', 'Ganons Tower (Tile Room)'),
('Ganons Tower (Tile Room) Key Door', 'Ganons Tower (Compass Room)'),
('Ganons Tower (Bottom) (East)', 'Ganons Tower (Bottom)'),
('Ganons Tower (Hookshot Room)', 'Ganons Tower (Hookshot Room)'),
('Ganons Tower (Map Room)', 'Ganons Tower (Map Room)'),
('Ganons Tower (Double Switch Room)', 'Ganons Tower (Firesnake Room)'),
('Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)'),
('Ganons Tower (Bottom) (West)', 'Ganons Tower (Bottom)'),
('Ganons Tower Big Key Door', 'Ganons Tower (Top)'),
('Ganons Tower Torch Rooms', 'Ganons Tower (Before Moldorm)'),
('Ganons Tower Moldorm Door', 'Ganons Tower (Moldorm)'),
('Ganons Tower Moldorm Gap', 'Agahnim 2'),
('Ganon Drop', 'Bottom of Pyramid'),
('Pyramid Drop', 'East Dark World')
]
]
inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'),
('Zoras River', 'Zoras River'),
@@ -3065,18 +3052,6 @@ inverted_mandatory_connections = [('Lake Hylia Central Island Pier', 'Lake Hylia
('Turtle Rock (Dark Room) (South)', 'Turtle Rock (Eye Bridge)'),
('Turtle Rock Dark Room (South)', 'Turtle Rock (Dark Room)'),
('Turtle Rock (Trinexx)', 'Turtle Rock (Trinexx)'),
('Ganons Tower (Tile Room)', 'Ganons Tower (Tile Room)'),
('Ganons Tower (Tile Room) Key Door', 'Ganons Tower (Compass Room)'),
('Ganons Tower (Bottom) (East)', 'Ganons Tower (Bottom)'),
('Ganons Tower (Hookshot Room)', 'Ganons Tower (Hookshot Room)'),
('Ganons Tower (Map Room)', 'Ganons Tower (Map Room)'),
('Ganons Tower (Double Switch Room)', 'Ganons Tower (Firesnake Room)'),
('Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)'),
('Ganons Tower (Bottom) (West)', 'Ganons Tower (Bottom)'),
('Ganons Tower Big Key Door', 'Ganons Tower (Top)'),
('Ganons Tower Torch Rooms', 'Ganons Tower (Before Moldorm)'),
('Ganons Tower Moldorm Door', 'Ganons Tower (Moldorm)'),
('Ganons Tower Moldorm Gap', 'Agahnim 2'),
('Ganon Drop', 'Bottom of Pyramid'),
('Pyramid Drop', 'East Dark World'),
('Post Aga Teleporter', 'Light World'),
@@ -3512,7 +3487,7 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Main L
('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'),
('Turtle Rock Isolated Ledge Entrance', 'TR Eye Bridge'),
('Ganons Tower', 'Ganons Tower (Entrance)'),
('Ganons Tower', 'GT Lobby'),
('Ganons Tower Exit', 'Dark Death Mountain (Top)')
]

View File

@@ -88,14 +88,6 @@ def main(args, seed=None):
for player in range(1, world.players + 1):
set_rules(world, player)
# todo: remove this later. this is for debugging
for player in range(1, world.players + 1):
all_state = world.get_all_state(keys=True)
for bossregion in ['Eastern Boss', 'Desert Boss', 'Hera Boss', 'Tower Agahnim 1', 'PoD Boss', 'Swamp Boss',
'Skull Boss', 'Thieves Boss', 'Ice Boss', 'Mire Boss', 'TR Boss']:
if world.get_region(bossregion, player) not in all_state.reachable_regions[player]:
raise Exception(bossregion + ' missing from generation')
logger.info('Placing Dungeon Prizes.')
fill_prizes(world)

View File

@@ -193,28 +193,6 @@ def create_regions(world, player):
create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Cave']),
create_cave_region(player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']),
create_dungeon_region(player, 'Ganons Tower (Entrance)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Torch', 'Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right'],
['Ganons Tower (Tile Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower Big Key Door', 'Ganons Tower Exit']),
create_dungeon_region(player, 'Ganons Tower (Tile Room)', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], ['Ganons Tower (Tile Room) Key Door']),
create_dungeon_region(player, 'Ganons Tower (Compass Room)', 'Ganon\'s Tower', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right',
'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right'],
['Ganons Tower (Bottom) (East)']),
create_dungeon_region(player, 'Ganons Tower (Hookshot Room)', 'Ganon\'s Tower', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right',
'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'],
['Ganons Tower (Map Room)', 'Ganons Tower (Double Switch Room)']),
create_dungeon_region(player, 'Ganons Tower (Map Room)', 'Ganon\'s Tower', ['Ganons Tower - Map Chest']),
create_dungeon_region(player, 'Ganons Tower (Firesnake Room)', 'Ganon\'s Tower', ['Ganons Tower - Firesnake Room'], ['Ganons Tower (Firesnake Room)']),
create_dungeon_region(player, 'Ganons Tower (Teleport Room)', 'Ganon\'s Tower', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right',
'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'],
['Ganons Tower (Bottom) (West)']),
create_dungeon_region(player, 'Ganons Tower (Bottom)', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Chest', 'Ganons Tower - Big Chest', 'Ganons Tower - Big Key Room - Left',
'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest']),
create_dungeon_region(player, 'Ganons Tower (Top)', 'Ganon\'s Tower', None, ['Ganons Tower Torch Rooms']),
create_dungeon_region(player, 'Ganons Tower (Before Moldorm)', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right',
'Ganons Tower - Pre-Moldorm Chest'], ['Ganons Tower Moldorm Door']),
create_dungeon_region(player, 'Ganons Tower (Moldorm)', 'Ganon\'s Tower', None, ['Ganons Tower Moldorm Gap']),
create_dungeon_region(player, 'Agahnim 2', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest', 'Agahnim 2'], None),
create_cave_region(player, 'Pyramid', 'a drop\'s exit', ['Ganon'], ['Ganon Drop']),
create_cave_region(player, 'Bottom of Pyramid', 'a drop\'s exit', None, ['Pyramid Exit']),
create_dw_region(player, 'Pyramid Ledge', None, ['Pyramid Entrance', 'Pyramid Drop']),
@@ -269,7 +247,6 @@ def create_regions(world, player):
create_dungeon_region(player, 'Eastern Pot Switch', 'Eastern Palace', None, ['Eastern Pot Switch WN', 'Eastern Pot Switch SE']),
create_dungeon_region(player, 'Eastern Map Balcony', 'Eastern Palace', None, ['Eastern Map Balcony WS', 'Eastern Map Balcony Hook Path']),
create_dungeon_region(player, 'Eastern Map Room', 'Eastern Palace', ['Eastern Palace - Map Chest'], ['Eastern Map Room NE', 'Eastern Map Room Drop Down']),
# create_dungeon_region(player, 'Eastern Compass Area', 'Eastern Palace', ['Eastern Palace - Compass Chest'], ['Eastern Compass Area E', 'Eastern Compass Area EN']),
create_dungeon_region(player, 'Eastern West Wing', 'Eastern Palace', None, ['Eastern West Wing E', 'Eastern West Wing WS']),
create_dungeon_region(player, 'Eastern Stalfos Spawn', 'Eastern Palace', None, ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW']),
create_dungeon_region(player, 'Eastern Compass Room', 'Eastern Palace', ['Eastern Palace - Compass Chest'], ['Eastern Compass Room EN', 'Eastern Compass Room SW']),
@@ -557,7 +534,7 @@ def create_regions(world, player):
create_dungeon_region(player, 'Mire Falling Bridge', 'Misery Mire', ['Misery Mire - Big Chest'], ['Mire Falling Bridge WS', 'Mire Falling Bridge W', 'Mire Falling Bridge WN']),
create_dungeon_region(player, 'Mire Map Spike Side', 'Misery Mire', None, ['Mire Map Spike Side EN', 'Mire Map Spike Side Drop Down', 'Mire Map Spike Side Blue Barrier']),
create_dungeon_region(player, 'Mire Map Spot', 'Misery Mire', ['Misery Mire - Map Chest'], ['Mire Map Spot WN', 'Mire Map Spot Blue Barrier']),
create_dungeon_region(player, 'Mire Crystal Dead End', 'Misery Mire', None, ['Mire Crystal Dead End Left Barrier', 'Mire Crystal Dead End Right Barrier', 'Mire Crystal Dead End NE']),
create_dungeon_region(player, 'Mire Crystal Dead End', 'Misery Mire', None, ['Mire Crystal Dead End Left Barrier', 'Mire Crystal Dead End Right Barrier', 'Mire Crystal Dead End NW']),
create_dungeon_region(player, 'Mire Hidden Shooters', 'Misery Mire', None, ['Mire Hidden Shooters SE', 'Mire Hidden Shooters WS', 'Mire Hidden Shooters ES', 'Mire Hidden Shooters NE']),
create_dungeon_region(player, 'Mire Cross', 'Misery Mire', None, ['Mire Cross ES', 'Mire Cross SW']),
create_dungeon_region(player, 'Mire Minibridge', 'Misery Mire', None, ['Mire Minibridge SE', 'Mire Minibridge NE']),
@@ -639,6 +616,91 @@ def create_regions(world, player):
create_dungeon_region(player, 'TR Boss', 'Turtle Rock', ['Turtle Rock - Boss', 'Turtle Rock - Prize'], ['TR Boss SW']),
# gt
create_dungeon_region(player, 'GT Lobby', 'Ganon\'s Tower', None, ['GT Lobby Left Down Stairs', 'GT Lobby Up Stairs', 'GT Lobby Right Down Stairs', 'Ganons Tower Exit']),
create_dungeon_region(player, 'GT Bob\'s Torch', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Torch'], ['GT Torch Up Stairs', 'GT Torch WN', 'GT Torch EN', 'GT Torch SW']),
create_dungeon_region(player, 'GT Hope Room', 'Ganon\'s Tower', ['Ganons Tower - Hope Room - Left', 'Ganons Tower - Hope Room - Right'], ['GT Hope Room Up Stairs', 'GT Hope Room WN', 'GT Hope Room EN']),
create_dungeon_region(player, 'GT Big Chest', 'Ganon\'s Tower', ['Ganons Tower - Big Chest'], ['GT Big Chest NW', 'GT Big Chest SW']),
create_dungeon_region(player, 'GT Blocked Stairs', 'Ganon\'s Tower', None, ['GT Blocked Stairs Down Stairs', 'GT Blocked Stairs Block Path']),
create_dungeon_region(player, 'GT Bob\'s Room', 'Ganon\'s Tower', ['Ganons Tower - Bob\'s Chest'], ['GT Bob\'s Room SE', 'GT Bob\'s Room Hole']),
create_dungeon_region(player, 'GT Tile Room', 'Ganon\'s Tower', ['Ganons Tower - Tile Room'], ['GT Tile Room WN', 'GT Tile Room EN']),
create_dungeon_region(player, 'GT Speed Torch', 'Ganon\'s Tower', None, ['GT Speed Torch WN', 'GT Speed Torch NE', 'GT Speed Torch WS', 'GT Speed Torch SE']),
create_dungeon_region(player, 'GT Pots n Blocks', 'Ganon\'s Tower', None, ['GT Pots n Blocks ES']),
create_dungeon_region(player, 'GT Crystal Conveyor', 'Ganon\'s Tower', None, ['GT Crystal Conveyor NE', 'GT Crystal Conveyor WN']),
create_dungeon_region(player, 'GT Compass Room', 'Ganon\'s Tower', ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', 'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right'],
['GT Compass Room EN', 'GT Compass Room Warp']),
create_dungeon_region(player, 'GT Invisible Bridges', 'Ganon\'s Tower', None, ['GT Invisible Bridges WS']),
create_dungeon_region(player, 'GT Invisible Catwalk', 'Ganon\'s Tower', None, ['GT Invisible Catwalk ES', 'GT Invisible Catwalk WS', 'GT Invisible Catwalk NW', 'GT Invisible Catwalk NE']),
create_dungeon_region(player, 'GT Conveyor Cross', 'Ganon\'s Tower', ['Ganons Tower - Conveyor Cross Pot Key'], ['GT Conveyor Cross EN', 'GT Conveyor Cross WN']),
create_dungeon_region(player, 'GT Hookshot East Platform', 'Ganon\'s Tower', None, ['GT Hookshot EN', 'GT Hookshot East-North Path', 'GT Hookshot East-South Path']),
create_dungeon_region(player, 'GT Hookshot North Platform', 'Ganon\'s Tower', None, ['GT Hookshot NW', 'GT Hookshot North-East Path', 'GT Hookshot North-South Path']),
create_dungeon_region(player, 'GT Hookshot South Platform', 'Ganon\'s Tower', None, ['GT Hookshot ES', 'GT Hookshot South-East Path', 'GT Hookshot South-North Path', 'GT Hookshot Platform Blue Barrier']),
create_dungeon_region(player, 'GT Hookshot South Entry', 'Ganon\'s Tower', None, ['GT Hookshot SW', 'GT Hookshot Entry Blue Barrier']),
create_dungeon_region(player, 'GT Map Room', 'Ganon\'s Tower', ['Ganons Tower - Map Chest'], ['GT Map Room WS']),
create_dungeon_region(player, 'GT Double Switch Entry', 'Ganon\'s Tower', None, ['GT Double Switch NW', 'GT Double Switch Orange Barrier', 'GT Double Switch Orange Barrier 2']),
create_dungeon_region(player, 'GT Double Switch Switches', 'Ganon\'s Tower', None, ['GT Double Switch Blue Path', 'GT Double Switch Orange Path']),
create_dungeon_region(player, 'GT Double Switch Transition', 'Ganon\'s Tower', None, ['GT Double Switch Transition Blue']),
create_dungeon_region(player, 'GT Double Switch Key Spot', 'Ganon\'s Tower', ['Ganons Tower - Double Switch Pot Key'], ['GT Double Switch Key Blue Path', 'GT Double Switch Key Orange Path']),
create_dungeon_region(player, 'GT Double Switch Exit', 'Ganon\'s Tower', None, ['GT Double Switch EN', 'GT Double Switch Blue Barrier']),
create_dungeon_region(player, 'GT Spike Crystals', 'Ganon\'s Tower', None, ['GT Spike Crystals WN', 'GT Spike Crystals Warp']),
create_dungeon_region(player, 'GT Warp Maze - Left Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Left Section Warp']),
create_dungeon_region(player, 'GT Warp Maze - Mid Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Mid Section Left Warp', 'GT Warp Maze - Mid Section Right Warp']),
create_dungeon_region(player, 'GT Warp Maze - Right Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Right Section Warp']),
create_dungeon_region(player, 'GT Warp Maze - Pit Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Pit Section Warp Spot']),
create_dungeon_region(player, 'GT Warp Maze - Pit Exit Warp Spot', 'Ganon\'s Tower', None, ['GT Warp Maze - Pit Exit Warp']),
create_dungeon_region(player, 'GT Warp Maze Exit Section', 'Ganon\'s Tower', None, ['GT Warp Maze (Pits) ES', 'GT Warp Maze Exit Section Warp Spot']),
create_dungeon_region(player, 'GT Firesnake Room', 'Ganon\'s Tower', None, ['GT Firesnake Room Hook Path']),
create_dungeon_region(player, 'GT Firesnake Room Ledge', 'Ganon\'s Tower', ['Ganons Tower - Firesnake Room'], ['GT Firesnake Room SW']),
create_dungeon_region(player, 'GT Warp Maze - Rail Choice', 'Ganon\'s Tower', None, ['GT Warp Maze (Rails) NW', 'GT Warp Maze - Rail Choice Left Warp', 'GT Warp Maze - Rail Choice Right Warp']),
create_dungeon_region(player, 'GT Warp Maze - Rando Rail', 'Ganon\'s Tower', None, ['GT Warp Maze (Rails) WS', 'GT Warp Maze - Rando Rail Warp']),
create_dungeon_region(player, 'GT Warp Maze - Main Rails', 'Ganon\'s Tower', None, ['GT Warp Maze - Main Rails Best Warp', 'GT Warp Maze - Main Rails Mid Left Warp', 'GT Warp Maze - Main Rails Mid Right Warp', 'GT Warp Maze - Main Rails Right Top Warp', 'GT Warp Maze - Main Rails Right Mid Warp']),
create_dungeon_region(player, 'GT Warp Maze - Pot Rail', 'Ganon\'s Tower', None, ['GT Warp Maze - Pot Rail Warp']),
create_dungeon_region(player, 'GT Trap Room', 'Ganon\'s Tower', None, ['GT Trap Room SE']),
create_dungeon_region(player, 'GT Conveyor Star Pits', 'Ganon\'s Tower', ['Ganons Tower - Conveyor Star Pits Pot Key'], ['GT Conveyor Star Pits EN']),
create_dungeon_region(player, 'GT Hidden Star', 'Ganon\'s Tower', None, ['GT Hidden Star ES', 'GT Hidden Star Warp']),
create_dungeon_region(player, 'GT DMs Room', 'Ganon\'s Tower', ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right',
'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right'], ['GT DMs Room SW']),
create_dungeon_region(player, 'GT Falling Bridge', 'Ganon\'s Tower', None, ['GT Falling Bridge WN', 'GT Falling Bridge WS']),
create_dungeon_region(player, 'GT Randomizer Room', 'Ganon\'s Tower', ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right',
'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right'], ['GT Randomizer Room ES']),
create_dungeon_region(player, 'GT Ice Armos', 'Ganon\'s Tower', None, ['GT Ice Armos NE', 'GT Ice Armos WS']),
create_dungeon_region(player, 'GT Big Key Room', 'Ganon\'s Tower', ['Ganons Tower - Big Key Room - Left',
'Ganons Tower - Big Key Room - Right', 'Ganons Tower - Big Key Chest'], ['GT Big Key Room SE']),
create_dungeon_region(player, 'GT Four Torches', 'Ganon\'s Tower', None, ['GT Four Torches Up Stairs', 'GT Four Torches NW', 'GT Four Torches ES']),
create_dungeon_region(player, 'GT Fairy Abyss', 'Ganon\'s Tower', None, ['GT Fairy Abyss SW']),
create_dungeon_region(player, 'GT Crystal Paths', 'Ganon\'s Tower', None, ['GT Crystal Paths Down Stairs', 'GT Crystal Paths SW']),
create_dungeon_region(player, 'GT Mimics 1', 'Ganon\'s Tower', None, ['GT Mimics 1 NW', 'GT Mimics 1 ES']),
create_dungeon_region(player, 'GT Mimics 2', 'Ganon\'s Tower', None, ['GT Mimics 2 WS', 'GT Mimics 2 NE']),
create_dungeon_region(player, 'GT Dash Hall', 'Ganon\'s Tower', None, ['GT Dash Hall SE', 'GT Dash Hall NE']),
create_dungeon_region(player, 'GT Hidden Spikes', 'Ganon\'s Tower', None, ['GT Hidden Spikes SE', 'GT Hidden Spikes EN']),
create_dungeon_region(player, 'GT Cannonball Bridge', 'Ganon\'s Tower', None, ['GT Cannonball Bridge WN', 'GT Cannonball Bridge Up Stairs', 'GT Cannonball Bridge SE']),
create_dungeon_region(player, 'GT Refill', 'Ganon\'s Tower', None, ['GT Refill NE']),
create_dungeon_region(player, 'GT Gauntlet 1', 'Ganon\'s Tower', None, ['GT Gauntlet 1 Down Stairs', 'GT Gauntlet 1 WN']),
create_dungeon_region(player, 'GT Gauntlet 2', 'Ganon\'s Tower', None, ['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW']),
create_dungeon_region(player, 'GT Gauntlet 3', 'Ganon\'s Tower', None, ['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW']),
create_dungeon_region(player, 'GT Gauntlet 4', 'Ganon\'s Tower', None, ['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW']),
create_dungeon_region(player, 'GT Gauntlet 5', 'Ganon\'s Tower', None, ['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS']),
create_dungeon_region(player, 'GT Beam Dash', 'Ganon\'s Tower', None, ['GT Beam Dash ES', 'GT Beam Dash WS']),
create_dungeon_region(player, 'GT Lanmolas 2', 'Ganon\'s Tower', None, ['GT Lanmolas 2 ES', 'GT Lanmolas 2 NW']),
create_dungeon_region(player, 'GT Quad Pot', 'Ganon\'s Tower', None, ['GT Quad Pot SW', 'GT Quad Pot Up Stairs']),
create_dungeon_region(player, 'GT Wizzrobes 1', 'Ganon\'s Tower', None, ['GT Wizzrobes 1 Down Stairs', 'GT Wizzrobes 1 SW']),
create_dungeon_region(player, 'GT Dashing Bridge', 'Ganon\'s Tower', None, ['GT Dashing Bridge NW', 'GT Dashing Bridge NE']),
create_dungeon_region(player, 'GT Wizzrobes 2', 'Ganon\'s Tower', None, ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE']),
create_dungeon_region(player, 'GT Conveyor Bridge', 'Ganon\'s Tower', None, ['GT Conveyor Bridge SE', 'GT Conveyor Bridge EN']),
create_dungeon_region(player, 'GT Torch Cross', 'Ganon\'s Tower', None, ['GT Torch Cross WN', 'GT Torch Cross ES']),
create_dungeon_region(player, 'GT Staredown', 'Ganon\'s Tower', None, ['GT Staredown WS', 'GT Staredown Up Ladder']),
create_dungeon_region(player, 'GT Falling Torches', 'Ganon\'s Tower', None, ['GT Falling Torches Down Ladder', 'GT Falling Torches NE', 'GT Falling Torches Hole']),
create_dungeon_region(player, 'GT Mini Helmasaur Room', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left',
'Ganons Tower - Mini Helmasaur Room - Right', 'Ganons Tower - Mini Helmasuar Key Drop'], ['GT Mini Helmasaur Room SE', 'GT Mini Helmasaur Room WN']),
create_dungeon_region(player, 'GT Bomb Conveyor', 'Ganon\'s Tower', None, ['GT Bomb Conveyor EN', 'GT Bomb Conveyor SW']),
create_dungeon_region(player, 'GT Crystal Circles', 'Ganon\'s Tower', None, ['GT Crystal Circles NW', 'GT Crystal Circles SW']),
create_dungeon_region(player, 'GT Left Moldorm Ledge', 'Ganon\'s Tower', None, ['GT Left Moldorm Ledge Drop Down', 'GT Left Moldorm Ledge NW']),
create_dungeon_region(player, 'GT Right Moldorm Ledge', 'Ganon\'s Tower', None, ['GT Right Moldorm Ledge Down Stairs', 'GT Right Moldorm Ledge Drop Down']),
create_dungeon_region(player, 'GT Moldorm', 'Ganon\'s Tower', None, ['GT Moldorm Hole', 'GT Moldorm Gap']),
create_dungeon_region(player, 'GT Moldorm Pit', 'Ganon\'s Tower', None, ['GT Moldorm Pit Up Stairs']),
create_dungeon_region(player, 'GT Validation', 'Ganon\'s Tower', ['Ganons Tower - Validation Chest'], ['GT Validation WS']),
create_dungeon_region(player, 'GT Frozen Over', 'Ganon\'s Tower', None, ['GT Frozen Over ES', 'GT Frozen Over Up Stairs']),
create_dungeon_region(player, 'GT Brightly Lit Hall', 'Ganon\'s Tower', None, ['GT Brightly Lit Hall Down Stairs', 'GT Brightly Lit Hall NW']),
create_dungeon_region(player, 'GT Agahnim 2', 'Ganon\'s Tower', ['Agahnim 2'], ['GT Agahnim 2 SW'])
]
for region_name, (room_id, shopkeeper, replaceable) in shop_table.items():
@@ -778,6 +840,10 @@ key_only_locations = {
'Misery Mire - Conveyor Crystal Key Drop': 'Small Key (Misery Mire)',
'Turtle Rock - Pokey 1 Key Drop': 'Small Key (Turtle Rock)',
'Turtle Rock - Pokey 2 Key Drop': 'Small Key (Turtle Rock)',
'Ganons Tower - Conveyor Cross Pot Key': 'Small Key (Ganons Tower)',
'Ganons Tower - Double Switch Pot Key': 'Small Key (Ganons Tower)',
'Ganons Tower - Conveyor Star Pits Pot Key': 'Small Key (Ganons Tower)',
'Ganons Tower - Mini Helmasuar Key Drop': 'Small Key (Ganons Tower)'
}
dungeon_events = [

4
Rom.py
View File

@@ -18,7 +18,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '9202f6cce45bd7ee04d1e969be29936b'
RANDOMIZERBASEHASH = 'f96bdced8c89426bd4d1380db8a02220'
class JsonRom(object):
@@ -930,7 +930,7 @@ def patch_rom(world, player, rom):
# compasses showing dungeon count
if world.clock_mode != 'off':
rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location
elif world.keysanity:
elif world.keysanity or world.doorShuffle != 'vanilla': # todo: turn off for basic?
rom.write_byte(0x18003C, 0x01) # show on pickup
else:
rom.write_byte(0x18003C, 0x00)

View File

@@ -55,7 +55,7 @@ def set_rules(world, player):
# if swamp and dam have not been moved we require mirror for swamp palace
if not world.swamp_patch_required[player]:
add_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has_Mirror(player))
add_rule(world.get_entrance('Swamp Lobby Moat', player), lambda state: state.has_Mirror(player))
if world.mode != 'inverted':
set_bunny_rules(world, player)
@@ -429,59 +429,44 @@ def global_rules(world, 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))
add_key_logic_rules(world, player) # todo - vanilla shuffle rules
set_rule(world.get_location('Ganons Tower - Bob\'s Torch', player), lambda state: state.has_Boots(player))
set_rule(world.get_entrance('GT Hope Room EN', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('GT Conveyor Cross WN', player), lambda state: state.has('Hammer', player))
set_rule(world.get_entrance('GT Speed Torch SE', player), lambda state: state.has('Fire Rod', player))
set_rule(world.get_entrance('GT Hookshot East-North Path', player), lambda state: state.has('Hookshot', player))
set_rule(world.get_entrance('GT Hookshot South-East Path', player), lambda state: state.has('Hookshot', player))
set_rule(world.get_entrance('GT Hookshot South-North Path', player), lambda state: state.has('Hookshot', player))
set_rule(world.get_entrance('GT Hookshot East-South Path', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
set_rule(world.get_entrance('GT Hookshot North-East Path', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
set_rule(world.get_entrance('GT Hookshot North-South Path', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
set_rule(world.get_entrance('GT Firesnake Room Hook Path', player), lambda state: state.has('Hookshot', player))
# I am tempted to stick an invincibility rule for getting across falling bridge
set_rule(world.get_location('Ganons Tower - Big Chest', player), lambda state: state.has('Big Key (Ganons Tower)', player))
if world.accessibility == 'locations':
forbid_item(world.get_location('Ganons Tower - Big Chest', player), 'Big Key (Ganons Tower)', player)
set_rule(world.get_entrance('GT Ice Armos NE', player), lambda state: world.get_region('GT Ice Armos', player).dungeon.bosses['bottom'].can_defeat(state))
set_rule(world.get_entrance('GT Ice Armos WS', player), lambda state: world.get_region('GT Ice Armos', player).dungeon.bosses['bottom'].can_defeat(state))
set_rule(world.get_entrance('GT Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
set_rule(world.get_entrance('GT Mimics 1 ES', player), lambda state: state.can_shoot_arrows(player))
set_rule(world.get_entrance('GT Mimics 2 WS', player), lambda state: state.can_shoot_arrows(player))
set_rule(world.get_entrance('GT Mimics 2 NE', player), lambda state: state.can_shoot_arrows(player))
set_rule(world.get_entrance('GT Dash Hall NE', player), lambda state: state.has('Big Key (Ganons Tower)', player))
# consider access to refill room
# consider can_kill_most_things to gauntlet
set_rule(world.get_entrance('GT Lanmolas 2 ES', player), lambda state: world.get_region('GT Lanmolas 2', player).dungeon.bosses['middle'].can_defeat(state))
set_rule(world.get_entrance('GT Lanmolas 2 NW', player), lambda state: world.get_region('GT Lanmolas 2', player).dungeon.bosses['middle'].can_defeat(state))
set_rule(world.get_entrance('GT Torch Cross ES', player), lambda state: state.has_fire_source(player))
set_rule(world.get_entrance('GT Falling Torches NE', player), lambda state: state.has_fire_source(player))
set_rule(world.get_entrance('GT Moldorm Gap', player), lambda state: state.has('Hookshot', player) and world.get_region('GT Moldorm', player).dungeon.bosses['top'].can_defeat(state))
set_rule(world.get_entrance('GT Brightly Lit Hall NW', player), lambda state: state.has('Big Key (Ganons Tower)', player))
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 2', player))
add_key_logic_rules(world, player)
# End of door rando rules.
add_rule(world.get_location('Sunken Treasure', player), lambda state: state.has('Open Floodgate', player))
# these key rules are conservative, you might be able to get away with more lenient rules
randomizer_room_chests = ['Ganons Tower - Randomizer Room - Top Left', 'Ganons Tower - Randomizer Room - Top Right', 'Ganons Tower - Randomizer Room - Bottom Left', 'Ganons Tower - Randomizer Room - Bottom Right']
compass_room_chests = ['Ganons Tower - Compass Room - Top Left', 'Ganons Tower - Compass Room - Top Right', 'Ganons Tower - Compass Room - Bottom Left', 'Ganons Tower - Compass Room - Bottom Right']
set_rule(world.get_location('Ganons Tower - Bob\'s Torch', player), lambda state: state.has_Boots(player))
set_rule(world.get_entrance('Ganons Tower (Tile Room)', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hammer', player))
set_rule(world.get_entrance('Ganons Tower (Map Room)', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 4) or (item_name(state, 'Ganons Tower - Map Chest', player) in [('Big Key (Ganons Tower)', player), ('Small Key (Ganons Tower)', player)] and state.has_key('Small Key (Ganons Tower)', player, 3)))
if world.accessibility != 'locations':
set_always_allow(world.get_location('Ganons Tower - Map Chest', player), lambda state, item: item.name == 'Small Key (Ganons Tower)' and item.player == player and state.has_key('Small Key (Ganons Tower)', player, 3))
else:
forbid_item(world.get_location('Ganons Tower - Map Chest', player), 'Small Key (Ganons Tower)', player)
# It is possible to need more than 2 keys to get through this entance if you spend keys elsewhere. We reflect this in the chest requirements.
# However we need to leave these at the lower values to derive that with 3 keys it is always possible to reach Bob and Ice Armos.
set_rule(world.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 2))
# It is possible to need more than 3 keys ....
set_rule(world.get_entrance('Ganons Tower (Firesnake Room)', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 3))
#The actual requirements for these rooms to avoid key-lock
set_rule(world.get_location('Ganons Tower - Firesnake Room', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 3) or (item_in_locations(state, 'Big Key (Ganons Tower)', player, zip(randomizer_room_chests, [player] * len(randomizer_room_chests))) and state.has_key('Small Key (Ganons Tower)', player, 2)))
for location in randomizer_room_chests:
set_rule(world.get_location(location, player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 4) or (item_in_locations(state, 'Big Key (Ganons Tower)', player, zip(randomizer_room_chests, [player] * len(randomizer_room_chests))) and state.has_key('Small Key (Ganons Tower)', player, 3)))
# Once again it is possible to need more than 3 keys...
set_rule(world.get_entrance('Ganons Tower (Tile Room) Key Door', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 3) and state.has('Fire Rod', player))
# Actual requirements
for location in compass_room_chests:
set_rule(world.get_location(location, player), lambda state: state.has('Fire Rod', player) and (state.has_key('Small Key (Ganons Tower)', player, 4) or (item_in_locations(state, 'Big Key (Ganons Tower)', player, zip(compass_room_chests, [player] * len(compass_room_chests))) and state.has_key('Small Key (Ganons Tower)', player, 3))))
set_rule(world.get_location('Ganons Tower - Big Chest', player), lambda state: state.has('Big Key (Ganons Tower)', player))
set_rule(world.get_location('Ganons Tower - Big Key Room - Left', player), lambda state: world.get_location('Ganons Tower - Big Key Room - Left', player).parent_region.dungeon.bosses['bottom'].can_defeat(state))
set_rule(world.get_location('Ganons Tower - Big Key Chest', player), lambda state: world.get_location('Ganons Tower - Big Key Chest', player).parent_region.dungeon.bosses['bottom'].can_defeat(state))
set_rule(world.get_location('Ganons Tower - Big Key Room - Right', player), lambda state: world.get_location('Ganons Tower - Big Key Room - Right', player).parent_region.dungeon.bosses['bottom'].can_defeat(state))
set_rule(world.get_entrance('Ganons Tower Big Key Door', player), lambda state: state.has('Big Key (Ganons Tower)', player) and state.can_shoot_arrows(player))
set_rule(world.get_entrance('Ganons Tower Torch Rooms', player), lambda state: state.has_fire_source(player) and world.get_entrance('Ganons Tower Torch Rooms', player).parent_region.dungeon.bosses['middle'].can_defeat(state))
set_rule(world.get_location('Ganons Tower - Pre-Moldorm Chest', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 3))
set_rule(world.get_entrance('Ganons Tower Moldorm Door', player), lambda state: state.has_key('Small Key (Ganons Tower)', player, 4))
set_rule(world.get_entrance('Ganons Tower Moldorm Gap', player), lambda state: state.has('Hookshot', player) and world.get_entrance('Ganons Tower Moldorm Gap', player).parent_region.dungeon.bosses['top'].can_defeat(state))
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 2', player))
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player))
for location in ['Ganons Tower - Big Chest', 'Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right',
'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Validation Chest']:
forbid_item(world.get_location(location, player), 'Big Key (Ganons Tower)', player)
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)
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
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
@@ -491,6 +476,7 @@ def global_rules(world, player):
set_rule(world.get_entrance('Ganons Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt, player))
def inverted_rules(world, player):
if world.goal == 'triforcehunt':
for location in world.get_locations():
@@ -897,11 +883,12 @@ def no_glitches_rules(world, player):
set_rule(world.get_entrance('Dark Lake Hylia Teleporter', player), lambda state: state.has('Flippers', player) and (state.has('Hammer', player) or state.can_lift_rocks(player)))
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop', player), lambda state: state.has('Flippers', player))
add_rule(world.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
add_rule(world.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has('Hookshot', player))
DMs_room_chests = ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right']
for location in DMs_room_chests:
add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
# todo: move some dungeon rules to no glictes logic - see these for examples
# add_rule(world.get_entrance('Ganons Tower (Hookshot Room)', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
# add_rule(world.get_entrance('Ganons Tower (Double Switch Room)', player), lambda state: state.has('Hookshot', player))
# DMs_room_chests = ['Ganons Tower - DMs Room - Top Left', 'Ganons Tower - DMs Room - Top Right', 'Ganons Tower - DMs Room - Bottom Left', 'Ganons Tower - DMs Room - Bottom Right']
# for location in DMs_room_chests:
# add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override
set_rule(world.get_entrance('Paradox Cave Bomb Jump', player), lambda state: False)

View File

@@ -7,8 +7,6 @@ RecordStairType: {
SpiralWarp: {
lda $040c : cmp.b #$ff : beq .abort ; abort if not in dungeon
cmp #$1a : bcs .abort ; abort if not supported yet -- todo: this needs to be altered/removed as more dungeons are implemented
.check
lda $045e : cmp #$5e : beq .gtg ; abort if not spiral - intended room is in A!
cmp #$5f : beq .gtg
.abort

File diff suppressed because one or more lines are too long