Merge in DoorDev
This commit is contained in:
@@ -7,7 +7,7 @@ from collections import OrderedDict, deque, defaultdict
|
|||||||
from EntranceShuffle import door_addresses
|
from EntranceShuffle import door_addresses
|
||||||
from _vendor.collections_extended import bag
|
from _vendor.collections_extended import bag
|
||||||
from Utils import int16_as_bytes
|
from Utils import int16_as_bytes
|
||||||
from Tables import normal_offset_table, spiral_offset_table
|
from Tables import normal_offset_table, spiral_offset_table, multiply_lookup, divisor_lookup
|
||||||
from RoomData import Room
|
from RoomData import Room
|
||||||
|
|
||||||
class World(object):
|
class World(object):
|
||||||
@@ -41,7 +41,7 @@ class World(object):
|
|||||||
self.shuffle_bonk_prizes = False
|
self.shuffle_bonk_prizes = False
|
||||||
self.light_world_light_cone = False
|
self.light_world_light_cone = False
|
||||||
self.dark_world_light_cone = False
|
self.dark_world_light_cone = False
|
||||||
self.clock_mode = 'off'
|
self.clock_mode = 'none'
|
||||||
self.rupoor_cost = 10
|
self.rupoor_cost = 10
|
||||||
self.aga_randomness = True
|
self.aga_randomness = True
|
||||||
self.lock_aga_door_in_escape = False
|
self.lock_aga_door_in_escape = False
|
||||||
@@ -1041,12 +1041,21 @@ hook_dir_map = {
|
|||||||
Direction.East: Hook.East,
|
Direction.East: Hook.East,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
edge_map = {
|
||||||
|
Direction.North: Hook.NEdge,
|
||||||
|
Direction.South: Hook.SEdge,
|
||||||
|
Direction.West: Hook.WEdge,
|
||||||
|
Direction.East: Hook.EEdge,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def hook_from_door(door):
|
def hook_from_door(door):
|
||||||
if door.type == DoorType.SpiralStairs:
|
if door.type == DoorType.SpiralStairs:
|
||||||
return Hook.Stairs
|
return Hook.Stairs
|
||||||
if door.type == DoorType.Normal:
|
if door.type == DoorType.Normal:
|
||||||
return hook_dir_map[door.direction]
|
return hook_dir_map[door.direction]
|
||||||
|
if door.type == DoorType.Open:
|
||||||
|
return edge_map[door.direction]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -1158,6 +1167,8 @@ class Door(object):
|
|||||||
self.zeroHzCam = False
|
self.zeroHzCam = False
|
||||||
self.zeroVtCam = False
|
self.zeroVtCam = False
|
||||||
self.doorListPos = -1
|
self.doorListPos = -1
|
||||||
|
self.edge_id = None
|
||||||
|
self.edge_width = None
|
||||||
|
|
||||||
# logical properties
|
# logical properties
|
||||||
# self.connected = False # combine with Dest?
|
# self.connected = False # combine with Dest?
|
||||||
@@ -1182,10 +1193,18 @@ class Door(object):
|
|||||||
return 0x13A000 + normal_offset_table[self.roomIndex] * 24 + (self.doorIndex + self.direction.value * 3) * 2
|
return 0x13A000 + normal_offset_table[self.roomIndex] * 24 + (self.doorIndex + self.direction.value * 3) * 2
|
||||||
elif self.type == DoorType.SpiralStairs:
|
elif self.type == DoorType.SpiralStairs:
|
||||||
return 0x13B000 + (spiral_offset_table[self.roomIndex] + self.doorIndex) * 4
|
return 0x13B000 + (spiral_offset_table[self.roomIndex] + self.doorIndex) * 4
|
||||||
|
elif self.type == DoorType.Open:
|
||||||
|
base_address = {
|
||||||
|
Direction.North: 0x13C500,
|
||||||
|
Direction.South: 0x13C533,
|
||||||
|
Direction.West: 0x13C566,
|
||||||
|
Direction.East: 0x13C581,
|
||||||
|
}
|
||||||
|
return base_address[self.direction] + self.edge_id * 3
|
||||||
|
|
||||||
def getTarget(self, toggle):
|
def getTarget(self, src):
|
||||||
if self.type == DoorType.Normal:
|
if self.type == DoorType.Normal:
|
||||||
bitmask = 4 * (self.layer ^ 1 if toggle else self.layer)
|
bitmask = 4 * (self.layer ^ 1 if src.toggle else self.layer)
|
||||||
bitmask += 0x08 * int(self.trapFlag)
|
bitmask += 0x08 * int(self.trapFlag)
|
||||||
return [self.roomIndex, bitmask + self.doorIndex]
|
return [self.roomIndex, bitmask + self.doorIndex]
|
||||||
if self.type == DoorType.SpiralStairs:
|
if self.type == DoorType.SpiralStairs:
|
||||||
@@ -1194,6 +1213,17 @@ class Door(object):
|
|||||||
bitmask += 0x20 * int(self.zeroVtCam)
|
bitmask += 0x20 * int(self.zeroVtCam)
|
||||||
bitmask += 0x80 if self.direction == Direction.Up else 0
|
bitmask += 0x80 if self.direction == Direction.Up else 0
|
||||||
return [self.roomIndex, bitmask + self.quadrant, self.shiftX, self.shiftY]
|
return [self.roomIndex, bitmask + self.quadrant, self.shiftX, self.shiftY]
|
||||||
|
if self.type == DoorType.Open:
|
||||||
|
bitmask = self.edge_id
|
||||||
|
bitmask += 0x10 * self.layer
|
||||||
|
bitmask += 0x20 * self.quadrant
|
||||||
|
bitmask += 0x80
|
||||||
|
if src.type == DoorType.Open:
|
||||||
|
fraction = 0x10 * multiply_lookup[src.edge_width][self.edge_width]
|
||||||
|
fraction += divisor_lookup[src.edge_width][self.edge_width]
|
||||||
|
return [self.roomIndex, bitmask, fraction]
|
||||||
|
else:
|
||||||
|
return [self.roomIndex, bitmask]
|
||||||
|
|
||||||
def dir(self, direction, room, doorIndex, layer):
|
def dir(self, direction, room, doorIndex, layer):
|
||||||
self.direction = direction
|
self.direction = direction
|
||||||
@@ -1210,6 +1240,12 @@ class Door(object):
|
|||||||
self.zeroVtCam = zero_vt_cam
|
self.zeroVtCam = zero_vt_cam
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def edge(self, edge_id, quadrant, width):
|
||||||
|
self.edge_id = edge_id
|
||||||
|
self.quadrant = quadrant
|
||||||
|
self.edge_width = width
|
||||||
|
return self
|
||||||
|
|
||||||
def small_key(self):
|
def small_key(self):
|
||||||
self.smallKey = True
|
self.smallKey = True
|
||||||
return self
|
return self
|
||||||
|
|||||||
6
CLI.py
6
CLI.py
@@ -188,7 +188,7 @@ def parse_arguments(argv, no_defaults=False):
|
|||||||
base game.
|
base game.
|
||||||
''')
|
''')
|
||||||
parser.add_argument('--experimental', default=defval(settings["experimental"] != 0), help='Enable experimental features', action='store_true')
|
parser.add_argument('--experimental', default=defval(settings["experimental"] != 0), help='Enable experimental features', action='store_true')
|
||||||
parser.add_argument('--dungeon_counters', default=defval(settings["dungeon_counters"]), help='Enable dungeon chest counters', const='off', nargs='?', choices=['off', 'on', 'pickup'])
|
parser.add_argument('--dungeon_counters', default=defval(settings["dungeon_counters"]), help='Enable dungeon chest counters', const='off', nargs='?', choices=['off', 'on', 'pickup', 'default'])
|
||||||
parser.add_argument('--crystals_ganon', default=defval(settings["crystals_ganon"]), const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'],
|
parser.add_argument('--crystals_ganon', default=defval(settings["crystals_ganon"]), const='7', nargs='?', choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'],
|
||||||
help='''\
|
help='''\
|
||||||
How many crystals are needed to defeat ganon. Any other
|
How many crystals are needed to defeat ganon. Any other
|
||||||
@@ -357,8 +357,8 @@ def get_settings():
|
|||||||
"bigkeyshuffle": False,
|
"bigkeyshuffle": False,
|
||||||
"keysanity": False,
|
"keysanity": False,
|
||||||
"door_shuffle": "basic",
|
"door_shuffle": "basic",
|
||||||
"experimental": 0,
|
"experimental": False,
|
||||||
"dungeon_counters": "off",
|
"dungeon_counters": "default",
|
||||||
|
|
||||||
"multi": 1,
|
"multi": 1,
|
||||||
"names": "",
|
"names": "",
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ def link_doors(world, player):
|
|||||||
# These connections are here because they are currently unable to be shuffled
|
# These connections are here because they are currently unable to be shuffled
|
||||||
for entrance, ext in straight_staircases:
|
for entrance, ext in straight_staircases:
|
||||||
connect_two_way(world, entrance, ext, player)
|
connect_two_way(world, entrance, ext, player)
|
||||||
for entrance, ext in open_edges:
|
|
||||||
connect_two_way(world, entrance, ext, player)
|
|
||||||
for exitName, regionName in falldown_pits:
|
for exitName, regionName in falldown_pits:
|
||||||
connect_simple_door(world, exitName, regionName, player)
|
connect_simple_door(world, exitName, regionName, player)
|
||||||
for exitName, regionName in dungeon_warps:
|
for exitName, regionName in dungeon_warps:
|
||||||
@@ -40,6 +38,8 @@ def link_doors(world, player):
|
|||||||
connect_two_way(world, ent, ext, player)
|
connect_two_way(world, ent, ext, player)
|
||||||
|
|
||||||
if world.doorShuffle[player] == 'vanilla':
|
if world.doorShuffle[player] == 'vanilla':
|
||||||
|
for entrance, ext in open_edges:
|
||||||
|
connect_two_way(world, entrance, ext, player)
|
||||||
for exitName, regionName in vanilla_logical_connections:
|
for exitName, regionName in vanilla_logical_connections:
|
||||||
connect_simple_door(world, exitName, regionName, player)
|
connect_simple_door(world, exitName, regionName, player)
|
||||||
for entrance, ext in spiral_staircases:
|
for entrance, ext in spiral_staircases:
|
||||||
@@ -50,8 +50,13 @@ def link_doors(world, player):
|
|||||||
connect_one_way(world, ent, ext, player)
|
connect_one_way(world, ent, ext, player)
|
||||||
vanilla_key_logic(world, player)
|
vanilla_key_logic(world, player)
|
||||||
elif world.doorShuffle[player] == 'basic':
|
elif world.doorShuffle[player] == 'basic':
|
||||||
|
# if not world.experimental[player]:
|
||||||
|
for entrance, ext in open_edges:
|
||||||
|
connect_two_way(world, entrance, ext, player)
|
||||||
within_dungeon(world, player)
|
within_dungeon(world, player)
|
||||||
elif world.doorShuffle[player] == 'crossed':
|
elif world.doorShuffle[player] == 'crossed':
|
||||||
|
for entrance, ext in open_edges:
|
||||||
|
connect_two_way(world, entrance, ext, player)
|
||||||
cross_dungeon(world, player)
|
cross_dungeon(world, player)
|
||||||
else:
|
else:
|
||||||
logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player])
|
logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player])
|
||||||
@@ -134,7 +139,7 @@ def vanilla_key_logic(world, player):
|
|||||||
|
|
||||||
enabled_entrances = {}
|
enabled_entrances = {}
|
||||||
sector_queue = deque(builders)
|
sector_queue = deque(builders)
|
||||||
last_key = None
|
last_key, loops = None, 0
|
||||||
while len(sector_queue) > 0:
|
while len(sector_queue) > 0:
|
||||||
builder = sector_queue.popleft()
|
builder = sector_queue.popleft()
|
||||||
|
|
||||||
@@ -142,12 +147,14 @@ def vanilla_key_logic(world, player):
|
|||||||
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, builder.name)
|
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, builder.name)
|
||||||
origin_list_sans_drops = remove_drop_origins(origin_list)
|
origin_list_sans_drops = remove_drop_origins(origin_list)
|
||||||
if len(origin_list_sans_drops) <= 0:
|
if len(origin_list_sans_drops) <= 0:
|
||||||
if last_key == builder.name:
|
if last_key == builder.name or loops > 1000:
|
||||||
raise Exception('Infinte loop detected %s' % builder.name)
|
origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name
|
||||||
|
raise Exception('Infinite loop detected for "%s" located at %s' % builder.name, origin_name)
|
||||||
sector_queue.append(builder)
|
sector_queue.append(builder)
|
||||||
last_key = builder.name
|
last_key = builder.name
|
||||||
|
loops += 1
|
||||||
else:
|
else:
|
||||||
find_new_entrances(builder.master_sector, connections, potentials, enabled_entrances, world, player)
|
find_new_entrances(builder.master_sector, entrances_map, connections, potentials, enabled_entrances, world, player)
|
||||||
start_regions = convert_regions(origin_list, world, player)
|
start_regions = convert_regions(origin_list, world, player)
|
||||||
doors = convert_key_doors(default_small_key_doors[builder.name], world, player)
|
doors = convert_key_doors(default_small_key_doors[builder.name], world, player)
|
||||||
key_layout = build_key_layout(builder, start_regions, doors, world, player)
|
key_layout = build_key_layout(builder, start_regions, doors, world, player)
|
||||||
@@ -160,7 +167,7 @@ def vanilla_key_logic(world, player):
|
|||||||
world.key_logic[player][builder.name] = key_layout.key_logic
|
world.key_logic[player][builder.name] = key_layout.key_logic
|
||||||
log_key_logic(builder.name, key_layout.key_logic)
|
log_key_logic(builder.name, key_layout.key_logic)
|
||||||
last_key = None
|
last_key = None
|
||||||
if world.shuffle[player] == 'vanilla' and world.accessibility[player] == 'items':
|
if world.shuffle[player] == 'vanilla' and world.accessibility[player] == 'items' and not world.retro[player]:
|
||||||
validate_vanilla_key_logic(world, player)
|
validate_vanilla_key_logic(world, player)
|
||||||
|
|
||||||
|
|
||||||
@@ -345,7 +352,7 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_
|
|||||||
entrances_map, potentials, connections = connections_tuple
|
entrances_map, potentials, connections = connections_tuple
|
||||||
enabled_entrances = {}
|
enabled_entrances = {}
|
||||||
sector_queue = deque(dungeon_builders.values())
|
sector_queue = deque(dungeon_builders.values())
|
||||||
last_key = None
|
last_key, loops = None, 0
|
||||||
while len(sector_queue) > 0:
|
while len(sector_queue) > 0:
|
||||||
builder = sector_queue.popleft()
|
builder = sector_queue.popleft()
|
||||||
split_dungeon = builder.name.startswith('Desert Palace') or builder.name.startswith('Skull Woods')
|
split_dungeon = builder.name.startswith('Desert Palace') or builder.name.startswith('Skull Woods')
|
||||||
@@ -356,14 +363,16 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_
|
|||||||
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, name)
|
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, name)
|
||||||
origin_list_sans_drops = remove_drop_origins(origin_list)
|
origin_list_sans_drops = remove_drop_origins(origin_list)
|
||||||
if len(origin_list_sans_drops) <= 0 or name == "Turtle Rock" and not validate_tr(builder, origin_list_sans_drops, world, player):
|
if len(origin_list_sans_drops) <= 0 or name == "Turtle Rock" and not validate_tr(builder, origin_list_sans_drops, world, player):
|
||||||
if last_key == builder.name:
|
if last_key == builder.name or loops > 1000:
|
||||||
raise Exception('Infinte loop detected %s' % builder.name)
|
origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name
|
||||||
|
raise Exception('Infinite loop detected for "%s" located at %s' % builder.name, origin_name)
|
||||||
sector_queue.append(builder)
|
sector_queue.append(builder)
|
||||||
last_key = builder.name
|
last_key = builder.name
|
||||||
|
loops += 1
|
||||||
else:
|
else:
|
||||||
logging.getLogger('').info('Generating dungeon: %s', builder.name)
|
logging.getLogger('').info('Generating dungeon: %s', builder.name)
|
||||||
ds = generate_dungeon(builder, origin_list_sans_drops, split_dungeon, world, player)
|
ds = generate_dungeon(builder, origin_list_sans_drops, split_dungeon, world, player)
|
||||||
find_new_entrances(ds, connections, potentials, enabled_entrances, world, player)
|
find_new_entrances(ds, entrances_map, connections, potentials, enabled_entrances, world, player)
|
||||||
ds.name = name
|
ds.name = name
|
||||||
builder.master_sector = ds
|
builder.master_sector = ds
|
||||||
builder.layout_starts = origin_list if len(builder.entrance_list) <= 0 else builder.entrance_list
|
builder.layout_starts = origin_list if len(builder.entrance_list) <= 0 else builder.entrance_list
|
||||||
@@ -420,9 +429,14 @@ def remove_drop_origins(entrance_list):
|
|||||||
return [x for x in entrance_list if x not in drop_entrances]
|
return [x for x in entrance_list if x not in drop_entrances]
|
||||||
|
|
||||||
|
|
||||||
def find_new_entrances(sector, connections, potentials, enabled, world, player):
|
def find_new_entrances(sector, entrances_map, connections, potentials, enabled, world, player):
|
||||||
for region in sector.regions:
|
for region in sector.regions:
|
||||||
if region.name in connections.keys() and (connections[region.name] in potentials.keys() or connections[region.name].name in world.inaccessible_regions[player]):
|
if region.name in connections.keys() and (connections[region.name] in potentials.keys() or connections[region.name].name in world.inaccessible_regions[player]):
|
||||||
|
enable_new_entrances(region, connections, potentials, enabled, world, player)
|
||||||
|
inverted_aga_check(entrances_map, connections, potentials, enabled, world, player)
|
||||||
|
|
||||||
|
|
||||||
|
def enable_new_entrances(region, connections, potentials, enabled, world, player):
|
||||||
new_region = connections[region.name]
|
new_region = connections[region.name]
|
||||||
if new_region in potentials.keys():
|
if new_region in potentials.keys():
|
||||||
for potential in potentials.pop(new_region):
|
for potential in potentials.pop(new_region):
|
||||||
@@ -443,6 +457,24 @@ def find_new_entrances(sector, connections, potentials, enabled, world, player):
|
|||||||
queue.append(new_exit)
|
queue.append(new_exit)
|
||||||
|
|
||||||
|
|
||||||
|
def inverted_aga_check(entrances_map, connections, potentials, enabled, world, player):
|
||||||
|
if world.mode[player] == 'inverted':
|
||||||
|
if 'Agahnims Tower' in entrances_map.keys() or aga_tower_enabled(enabled):
|
||||||
|
for region in list(potentials.keys()):
|
||||||
|
if region.name == 'Hyrule Castle Ledge':
|
||||||
|
for r_name in potentials[region]:
|
||||||
|
new_region = world.get_region(r_name, player)
|
||||||
|
enable_new_entrances(new_region, connections, potentials, enabled, world, player)
|
||||||
|
|
||||||
|
|
||||||
|
def aga_tower_enabled(enabled):
|
||||||
|
for region_name, enabled_tuple in enabled.items():
|
||||||
|
entrance, dungeon = enabled_tuple
|
||||||
|
if dungeon.name == 'Agahnims Tower':
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def within_dungeon_legacy(world, player):
|
def within_dungeon_legacy(world, player):
|
||||||
# TODO: The "starts" regions need access logic
|
# TODO: The "starts" regions need access logic
|
||||||
# Aerinon's note: I think this is handled already by ER Rules - may need to check correct requirements
|
# Aerinon's note: I think this is handled already by ER Rules - may need to check correct requirements
|
||||||
@@ -812,7 +844,7 @@ def convert_to_sectors(region_names, world, player):
|
|||||||
matching_sectors = []
|
matching_sectors = []
|
||||||
while len(exits) > 0:
|
while len(exits) > 0:
|
||||||
ext = exits.pop()
|
ext = exits.pop()
|
||||||
door = world.check_for_door(ext.name, player)
|
door = ext.door
|
||||||
if ext.connected_region is not None or door is not None and door.controller is not None:
|
if ext.connected_region is not None or door is not None and door.controller is not None:
|
||||||
if door is not None and door.controller is not None:
|
if door is not None and door.controller is not None:
|
||||||
connect_region = world.get_entrance(door.controller.name, player).parent_region
|
connect_region = world.get_entrance(door.controller.name, player).parent_region
|
||||||
@@ -1685,7 +1717,7 @@ open_edges = [
|
|||||||
('Thieves Ambush EN Edge', 'Thieves BK Corner WN Edge'),
|
('Thieves Ambush EN Edge', 'Thieves BK Corner WN Edge'),
|
||||||
('Thieves BK Corner S Edge', 'Thieves Compass Room N Edge'),
|
('Thieves BK Corner S Edge', 'Thieves Compass Room N Edge'),
|
||||||
('Thieves BK Corner SW Edge', 'Thieves Compass Room NW Edge'),
|
('Thieves BK Corner SW Edge', 'Thieves Compass Room NW Edge'),
|
||||||
('Thieves Compass Room WS Edge', 'Thieves Big Chest Nook WS Edge'),
|
('Thieves Compass Room WS Edge', 'Thieves Big Chest Nook ES Edge'),
|
||||||
('Thieves Cricket Hall Left Edge', 'Thieves Cricket Hall Right Edge')
|
('Thieves Cricket Hall Left Edge', 'Thieves Cricket Hall Right Edge')
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1935,7 +1967,7 @@ interior_doors = [
|
|||||||
|
|
||||||
key_doors = [
|
key_doors = [
|
||||||
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
|
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
|
||||||
('Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S'),
|
('Sewers Dark Cross Key Door N', 'Sewers Water S'),
|
||||||
('Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN'),
|
('Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN'),
|
||||||
('Eastern Darkness Up Stairs', 'Eastern Attic Start Down Stairs'),
|
('Eastern Darkness Up Stairs', 'Eastern Attic Start Down Stairs'),
|
||||||
('Eastern Big Key NE', 'Eastern Hint Tile Blocked Path SE'),
|
('Eastern Big Key NE', 'Eastern Hint Tile Blocked Path SE'),
|
||||||
@@ -1955,7 +1987,7 @@ key_doors = [
|
|||||||
default_small_key_doors = {
|
default_small_key_doors = {
|
||||||
'Hyrule Castle': [
|
'Hyrule Castle': [
|
||||||
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
|
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
|
||||||
('Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S'),
|
('Sewers Dark Cross Key Door N', 'Sewers Water S'),
|
||||||
('Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon North Abyss Key Door N'),
|
('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')
|
('Hyrule Dungeon Armory Interior Key Door N', 'Hyrule Dungeon Armory Interior Key Door S')
|
||||||
],
|
],
|
||||||
@@ -2053,7 +2085,7 @@ default_door_connections = [
|
|||||||
('Hyrule Castle West Hall E', 'Hyrule Castle Back Hall W'),
|
('Hyrule Castle West Hall E', 'Hyrule Castle Back Hall W'),
|
||||||
('Hyrule Castle Throne Room N', 'Sewers Behind Tapestry S'),
|
('Hyrule Castle Throne Room N', 'Sewers Behind Tapestry S'),
|
||||||
('Hyrule Dungeon Guardroom N', 'Hyrule Dungeon Armory S'),
|
('Hyrule Dungeon Guardroom N', 'Hyrule Dungeon Armory S'),
|
||||||
('Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S'),
|
('Sewers Dark Cross Key Door N', 'Sewers Water S'),
|
||||||
('Sewers Water W', 'Sewers Key Rat E'),
|
('Sewers Water W', 'Sewers Key Rat E'),
|
||||||
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
|
('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'),
|
||||||
('Eastern Lobby Bridge N', 'Eastern Cannonball S'),
|
('Eastern Lobby Bridge N', 'Eastern Cannonball S'),
|
||||||
|
|||||||
84
Doors.py
84
Doors.py
@@ -68,15 +68,15 @@ def create_doors(world, player):
|
|||||||
create_door(player, 'Hyrule Dungeon Map Room Up Stairs', Sprl).dir(Up, 0x72, 0, LTH).ss(A, 0x4b, 0xec),
|
create_door(player, 'Hyrule Dungeon Map Room Up Stairs', Sprl).dir(Up, 0x72, 0, LTH).ss(A, 0x4b, 0xec),
|
||||||
create_door(player, 'Hyrule Dungeon Map Room Key Door S', Intr).dir(So, 0x72, Mid, High).small_key().pos(0),
|
create_door(player, 'Hyrule Dungeon Map Room Key Door S', Intr).dir(So, 0x72, Mid, High).small_key().pos(0),
|
||||||
create_door(player, 'Hyrule Dungeon North Abyss Key Door N', Intr).dir(No, 0x72, Mid, High).small_key().pos(0),
|
create_door(player, 'Hyrule Dungeon North Abyss Key Door N', Intr).dir(No, 0x72, Mid, High).small_key().pos(0),
|
||||||
create_door(player, 'Hyrule Dungeon North Abyss South Edge', Open).dir(So, 0x72, None, Low),
|
create_door(player, 'Hyrule Dungeon North Abyss South Edge', Open).dir(So, 0x72, None, Low).edge(0, Z, 0x10),
|
||||||
create_door(player, 'Hyrule Dungeon North Abyss Catwalk Edge', Open).dir(So, 0x72, None, High),
|
create_door(player, 'Hyrule Dungeon North Abyss Catwalk Edge', Open).dir(So, 0x72, None, High).edge(1, Z, 0x08),
|
||||||
create_door(player, 'Hyrule Dungeon North Abyss Catwalk Dropdown', Lgcl),
|
create_door(player, 'Hyrule Dungeon North Abyss Catwalk Dropdown', Lgcl),
|
||||||
create_door(player, 'Hyrule Dungeon South Abyss North Edge', Open).dir(No, 0x82, None, Low),
|
create_door(player, 'Hyrule Dungeon South Abyss North Edge', Open).dir(No, 0x82, None, Low).edge(0, A, 0x10),
|
||||||
create_door(player, 'Hyrule Dungeon South Abyss West Edge', Open).dir(We, 0x82, None, Low),
|
create_door(player, 'Hyrule Dungeon South Abyss West Edge', Open).dir(We, 0x82, None, Low).edge(3, Z, 0x10),
|
||||||
create_door(player, 'Hyrule Dungeon South Abyss Catwalk North Edge', Open).dir(No, 0x82, None, High),
|
create_door(player, 'Hyrule Dungeon South Abyss Catwalk North Edge', Open).dir(No, 0x82, None, High).edge(1, A, 0x08),
|
||||||
create_door(player, 'Hyrule Dungeon South Abyss Catwalk West Edge', Open).dir(We, 0x82, None, High),
|
create_door(player, 'Hyrule Dungeon South Abyss Catwalk West Edge', Open).dir(We, 0x82, None, High).edge(4, A, 0x18),
|
||||||
create_door(player, 'Hyrule Dungeon Guardroom Catwalk Edge', Open).dir(Ea, 0x81, None, High),
|
create_door(player, 'Hyrule Dungeon Guardroom Catwalk Edge', Open).dir(Ea, 0x81, None, High).edge(3, S, 0x10),
|
||||||
create_door(player, 'Hyrule Dungeon Guardroom Abyss Edge', Open).dir(We, 0x81, None, High),
|
create_door(player, 'Hyrule Dungeon Guardroom Abyss Edge', Open).dir(Ea, 0x81, None, High).edge(4, X, 0x18),
|
||||||
create_door(player, 'Hyrule Dungeon Guardroom N', Nrml).dir(No, 0x81, Left, Low).pos(0),
|
create_door(player, 'Hyrule Dungeon Guardroom N', Nrml).dir(No, 0x81, Left, Low).pos(0),
|
||||||
create_door(player, 'Hyrule Dungeon Armory S', Nrml).dir(So, 0x71, Left, Low).trap(0x2).pos(1),
|
create_door(player, 'Hyrule Dungeon Armory S', Nrml).dir(So, 0x71, Left, Low).trap(0x2).pos(1),
|
||||||
create_door(player, 'Hyrule Dungeon Armory ES', Intr).dir(Ea, 0x71, Left, Low).pos(2),
|
create_door(player, 'Hyrule Dungeon Armory ES', Intr).dir(Ea, 0x71, Left, Low).pos(2),
|
||||||
@@ -95,7 +95,7 @@ def create_doors(world, player):
|
|||||||
create_door(player, 'Sewers Rope Room North Stairs', StrS).dir(No, 0x42, Mid, High),
|
create_door(player, 'Sewers Rope Room North Stairs', StrS).dir(No, 0x42, Mid, High),
|
||||||
create_door(player, 'Sewers Dark Cross South Stairs', StrS).dir(So, 0x32, Mid, High),
|
create_door(player, 'Sewers Dark Cross South Stairs', StrS).dir(So, 0x32, Mid, High),
|
||||||
create_door(player, 'Sewers Dark Cross Key Door N', Nrml).dir(No, 0x32, Mid, High).small_key().pos(0),
|
create_door(player, 'Sewers Dark Cross Key Door N', Nrml).dir(No, 0x32, Mid, High).small_key().pos(0),
|
||||||
create_door(player, 'Sewers Dark Cross Key Door S', Nrml).dir(So, 0x22, Mid, High).small_key().pos(0),
|
create_door(player, 'Sewers Water S', Nrml).dir(So, 0x22, Mid, High).small_key().pos(0),
|
||||||
create_door(player, 'Sewers Water W', Nrml).dir(We, 0x22, Bot, High).pos(1),
|
create_door(player, 'Sewers Water W', Nrml).dir(We, 0x22, Bot, High).pos(1),
|
||||||
create_door(player, 'Sewers Key Rat E', Nrml).dir(Ea, 0x21, Bot, High).pos(1),
|
create_door(player, 'Sewers Key Rat E', Nrml).dir(Ea, 0x21, Bot, High).pos(1),
|
||||||
create_door(player, 'Sewers Key Rat Key Door N', Nrml).dir(No, 0x21, Right, High).small_key().pos(0),
|
create_door(player, 'Sewers Key Rat Key Door N', Nrml).dir(No, 0x21, Right, High).small_key().pos(0),
|
||||||
@@ -178,44 +178,44 @@ def create_doors(world, player):
|
|||||||
create_door(player, 'Eastern Boss SE', Nrml).dir(So, 0xc8, Right, High).no_exit().trap(0x4).pos(0),
|
create_door(player, 'Eastern Boss SE', Nrml).dir(So, 0xc8, Right, High).no_exit().trap(0x4).pos(0),
|
||||||
|
|
||||||
# Desert Palace
|
# Desert Palace
|
||||||
create_door(player, 'Desert Main Lobby NW Edge', Open).dir(No, 0x84, None, High),
|
create_door(player, 'Desert Main Lobby NW Edge', Open).dir(No, 0x84, None, High).edge(3, A, 0x20),
|
||||||
create_door(player, 'Desert Main Lobby N Edge', Open).dir(No, 0x84, None, High),
|
create_door(player, 'Desert Main Lobby N Edge', Open).dir(No, 0x84, None, High).edge(4, A, 0xa0),
|
||||||
create_door(player, 'Desert Main Lobby NE Edge', Open).dir(No, 0x84, None, High),
|
create_door(player, 'Desert Main Lobby NE Edge', Open).dir(No, 0x84, None, High).edge(5, S, 0x20),
|
||||||
create_door(player, 'Desert Main Lobby E Edge', Open).dir(Ea, 0x84, None, High),
|
create_door(player, 'Desert Main Lobby E Edge', Open).dir(Ea, 0x84, None, High).edge(5, S, 0xa0),
|
||||||
create_door(player, 'Desert Main Lobby Left Path', Lgcl),
|
create_door(player, 'Desert Main Lobby Left Path', Lgcl),
|
||||||
create_door(player, 'Desert Main Lobby Right Path', Lgcl),
|
create_door(player, 'Desert Main Lobby Right Path', Lgcl),
|
||||||
create_door(player, 'Desert Left Alcove Path', Lgcl),
|
create_door(player, 'Desert Left Alcove Path', Lgcl),
|
||||||
create_door(player, 'Desert Right Alcove Path', Lgcl),
|
create_door(player, 'Desert Right Alcove Path', Lgcl),
|
||||||
create_door(player, 'Desert Dead End Edge', Open).dir(So, 0x74, None, High),
|
create_door(player, 'Desert Dead End Edge', Open).dir(So, 0x74, None, High).edge(4, Z, 0xa0),
|
||||||
create_door(player, 'Desert East Wing W Edge', Open).dir(We, 0x85, None, High),
|
create_door(player, 'Desert East Wing W Edge', Open).dir(We, 0x85, None, High).edge(5, A, 0xa0),
|
||||||
create_door(player, 'Desert East Wing N Edge', Open).dir(No, 0x85, None, High),
|
create_door(player, 'Desert East Wing N Edge', Open).dir(No, 0x85, None, High).edge(6, A, 0x20),
|
||||||
create_door(player, 'Desert East Lobby WS', Intr).dir(We, 0x85, Bot, High).pos(3),
|
create_door(player, 'Desert East Lobby WS', Intr).dir(We, 0x85, Bot, High).pos(3),
|
||||||
create_door(player, 'Desert East Wing ES', Intr).dir(Ea, 0x85, Bot, High).pos(3),
|
create_door(player, 'Desert East Wing ES', Intr).dir(Ea, 0x85, Bot, High).pos(3),
|
||||||
create_door(player, 'Desert East Wing Key Door EN', Intr).dir(Ea, 0x85, Top, High).small_key().pos(1),
|
create_door(player, 'Desert East Wing Key Door EN', Intr).dir(Ea, 0x85, Top, High).small_key().pos(1),
|
||||||
create_door(player, 'Desert Compass Key Door WN', Intr).dir(We, 0x85, Top, High).small_key().pos(1),
|
create_door(player, 'Desert Compass Key Door WN', Intr).dir(We, 0x85, Top, High).small_key().pos(1),
|
||||||
create_door(player, 'Desert Compass NW', Nrml).dir(No, 0x85, Right, High).trap(0x4).pos(0),
|
create_door(player, 'Desert Compass NW', Nrml).dir(No, 0x85, Right, High).trap(0x4).pos(0),
|
||||||
create_door(player, 'Desert Cannonball S', Nrml).dir(So, 0x75, Right, High).pos(1),
|
create_door(player, 'Desert Cannonball S', Nrml).dir(So, 0x75, Right, High).pos(1),
|
||||||
create_door(player, 'Desert Arrow Pot Corner S Edge', Open).dir(So, 0x75, None, High),
|
create_door(player, 'Desert Arrow Pot Corner S Edge', Open).dir(So, 0x75, None, High).edge(6, Z, 0x20),
|
||||||
create_door(player, 'Desert Arrow Pot Corner W Edge', Open).dir(We, 0x75, None, High),
|
create_door(player, 'Desert Arrow Pot Corner W Edge', Open).dir(We, 0x75, None, High).edge(2, Z, 0x20),
|
||||||
create_door(player, 'Desert Arrow Pot Corner NW', Intr).dir(No, 0x75, Left, High).pos(0),
|
create_door(player, 'Desert Arrow Pot Corner NW', Intr).dir(No, 0x75, Left, High).pos(0),
|
||||||
create_door(player, 'Desert Trap Room SW', Intr).dir(So, 0x75, Left, High).pos(0),
|
create_door(player, 'Desert Trap Room SW', Intr).dir(So, 0x75, Left, High).pos(0),
|
||||||
create_door(player, 'Desert North Hall SE Edge', Open).dir(So, 0x74, None, High),
|
create_door(player, 'Desert North Hall SE Edge', Open).dir(So, 0x74, None, High).edge(5, X, 0x20),
|
||||||
create_door(player, 'Desert North Hall SW Edge', Open).dir(So, 0x74, None, High),
|
create_door(player, 'Desert North Hall SW Edge', Open).dir(So, 0x74, None, High).edge(3, Z, 0x20),
|
||||||
create_door(player, 'Desert North Hall W Edge', Open).dir(We, 0x74, None, High),
|
create_door(player, 'Desert North Hall W Edge', Open).dir(We, 0x74, None, High).edge(2, Z, 0x20),
|
||||||
create_door(player, 'Desert North Hall E Edge', Open).dir(Ea, 0x74, None, High),
|
create_door(player, 'Desert North Hall E Edge', Open).dir(Ea, 0x74, None, High).edge(1, X, 0x20),
|
||||||
create_door(player, 'Desert North Hall NW', Intr).dir(No, 0x74, Left, High).pos(1),
|
create_door(player, 'Desert North Hall NW', Intr).dir(No, 0x74, Left, High).pos(1),
|
||||||
create_door(player, 'Desert Map SW', Intr).dir(So, 0x74, Left, High).pos(1),
|
create_door(player, 'Desert Map SW', Intr).dir(So, 0x74, Left, High).pos(1),
|
||||||
create_door(player, 'Desert North Hall NE', Intr).dir(No, 0x74, Right, High).pos(0),
|
create_door(player, 'Desert North Hall NE', Intr).dir(No, 0x74, Right, High).pos(0),
|
||||||
create_door(player, 'Desert Map SE', Intr).dir(So, 0x74, Right, High).pos(0),
|
create_door(player, 'Desert Map SE', Intr).dir(So, 0x74, Right, High).pos(0),
|
||||||
create_door(player, 'Desert Sandworm Corner S Edge', Open).dir(So, 0x73, None, High),
|
create_door(player, 'Desert Sandworm Corner S Edge', Open).dir(So, 0x73, None, High).edge(2, X, 0x20),
|
||||||
create_door(player, 'Desert Sandworm Corner E Edge', Open).dir(Ea, 0x73, None, High),
|
create_door(player, 'Desert Sandworm Corner E Edge', Open).dir(Ea, 0x73, None, High).edge(1, X, 0x20),
|
||||||
create_door(player, 'Desert Sandworm Corner NE', Intr).dir(No, 0x73, Right, High).pos(2),
|
create_door(player, 'Desert Sandworm Corner NE', Intr).dir(No, 0x73, Right, High).pos(2),
|
||||||
create_door(player, 'Desert Bonk Torch SE', Intr).dir(So, 0x73, Right, High).pos(2),
|
create_door(player, 'Desert Bonk Torch SE', Intr).dir(So, 0x73, Right, High).pos(2),
|
||||||
create_door(player, 'Desert Sandworm Corner WS', Intr).dir(We, 0x73, Bot, High).pos(1),
|
create_door(player, 'Desert Sandworm Corner WS', Intr).dir(We, 0x73, Bot, High).pos(1),
|
||||||
create_door(player, 'Desert Circle of Pots ES', Intr).dir(Ea, 0x73, Bot, High).pos(1),
|
create_door(player, 'Desert Circle of Pots ES', Intr).dir(Ea, 0x73, Bot, High).pos(1),
|
||||||
create_door(player, 'Desert Circle of Pots NW', Intr).dir(No, 0x73, Left, High).pos(0),
|
create_door(player, 'Desert Circle of Pots NW', Intr).dir(No, 0x73, Left, High).pos(0),
|
||||||
create_door(player, 'Desert Big Chest SW', Intr).dir(So, 0x73, Left, High).pos(0),
|
create_door(player, 'Desert Big Chest SW', Intr).dir(So, 0x73, Left, High).pos(0),
|
||||||
create_door(player, 'Desert West Wing N Edge', Open).dir(No, 0x83, None, High),
|
create_door(player, 'Desert West Wing N Edge', Open).dir(No, 0x83, None, High).edge(2, S, 0x20),
|
||||||
create_door(player, 'Desert West Wing WS', Intr).dir(We, 0x83, Bot, High).pos(2),
|
create_door(player, 'Desert West Wing WS', Intr).dir(We, 0x83, Bot, High).pos(2),
|
||||||
create_door(player, 'Desert West Lobby ES', Intr).dir(Ea, 0x83, Bot, High).pos(2),
|
create_door(player, 'Desert West Lobby ES', Intr).dir(Ea, 0x83, Bot, High).pos(2),
|
||||||
create_door(player, 'Desert West Lobby NW', Intr).dir(No, 0x83, Left, High).pos(0),
|
create_door(player, 'Desert West Lobby NW', Intr).dir(No, 0x83, Left, High).pos(0),
|
||||||
@@ -537,26 +537,26 @@ def create_doors(world, player):
|
|||||||
create_door(player, 'Skull Final Drop WS', Intr).dir(We, 0x39, Bot, High).small_key().pos(1),
|
create_door(player, 'Skull Final Drop WS', Intr).dir(We, 0x39, Bot, High).small_key().pos(1),
|
||||||
create_door(player, 'Skull Final Drop Hole', Hole),
|
create_door(player, 'Skull Final Drop Hole', Hole),
|
||||||
|
|
||||||
create_door(player, 'Thieves Lobby N Edge', Open).dir(No, 0xdb, None, Low),
|
create_door(player, 'Thieves Lobby N Edge', Open).dir(No, 0xdb, None, Low).edge(7, A, 0x10),
|
||||||
create_door(player, 'Thieves Lobby NE Edge', Open).dir(No, 0xdb, None, Low),
|
create_door(player, 'Thieves Lobby NE Edge', Open).dir(No, 0xdb, None, Low).edge(8, S, 0x18),
|
||||||
create_door(player, 'Thieves Lobby E', Nrml).dir(Ea, 0xdb, Mid, High).no_exit().trap(0x4).pos(0),
|
create_door(player, 'Thieves Lobby E', Nrml).dir(Ea, 0xdb, Mid, High).no_exit().trap(0x4).pos(0),
|
||||||
create_door(player, 'Thieves Big Chest Nook WS Edge', Open).dir(We, 0xdb, None, Low),
|
create_door(player, 'Thieves Big Chest Nook ES Edge', Open).dir(Ea, 0xdb, None, Low).edge(8, X, 0x50),
|
||||||
create_door(player, 'Thieves Ambush S Edge', Open).dir(So, 0xcb, None, Low),
|
create_door(player, 'Thieves Ambush S Edge', Open).dir(So, 0xcb, None, Low).edge(7, Z, 0x10),
|
||||||
create_door(player, 'Thieves Ambush SE Edge', Open).dir(So, 0xcb, None, Low),
|
create_door(player, 'Thieves Ambush SE Edge', Open).dir(So, 0xcb, None, Low).edge(8, X, 0x18),
|
||||||
create_door(player, 'Thieves Ambush ES Edge', Open).dir(Ea, 0xcb, None, Low),
|
create_door(player, 'Thieves Ambush ES Edge', Open).dir(Ea, 0xcb, None, Low).edge(6, X, 0x50),
|
||||||
create_door(player, 'Thieves Ambush EN Edge', Open).dir(Ea, 0xcb, None, Low),
|
create_door(player, 'Thieves Ambush EN Edge', Open).dir(Ea, 0xcb, None, Low).edge(7, S, 0x50),
|
||||||
create_door(player, 'Thieves Ambush E', Nrml).dir(Ea, 0xcb, Mid, High).pos(0),
|
create_door(player, 'Thieves Ambush E', Nrml).dir(Ea, 0xcb, Mid, High).pos(0),
|
||||||
create_door(player, 'Thieves BK Corner WN Edge', Open).dir(We, 0xcc, None, Low),
|
create_door(player, 'Thieves BK Corner WN Edge', Open).dir(We, 0xcc, None, Low).edge(7, A, 0x50),
|
||||||
create_door(player, 'Thieves BK Corner WS Edge', Open).dir(We, 0xcc, None, Low),
|
create_door(player, 'Thieves BK Corner WS Edge', Open).dir(We, 0xcc, None, Low).edge(6, Z, 0x50),
|
||||||
create_door(player, 'Thieves BK Corner S Edge', Open).dir(So, 0xcc, None, Low),
|
create_door(player, 'Thieves BK Corner S Edge', Open).dir(So, 0xcc, None, Low).edge(10, Z, 0x10),
|
||||||
create_door(player, 'Thieves BK Corner SW Edge', Open).dir(So, 0xcc, None, Low),
|
create_door(player, 'Thieves BK Corner SW Edge', Open).dir(So, 0xcc, None, Low).edge(9, Z, 0x18),
|
||||||
create_door(player, 'Thieves Rail Ledge Drop Down', Lgcl),
|
create_door(player, 'Thieves Rail Ledge Drop Down', Lgcl),
|
||||||
create_door(player, 'Thieves Rail Ledge W', Nrml).dir(We, 0xcc, Mid, High).pos(2),
|
create_door(player, 'Thieves Rail Ledge W', Nrml).dir(We, 0xcc, Mid, High).pos(2),
|
||||||
create_door(player, 'Thieves Rail Ledge NW', Nrml).dir(No, 0xcc, Left, High).pos(1),
|
create_door(player, 'Thieves Rail Ledge NW', Nrml).dir(No, 0xcc, Left, High).pos(1),
|
||||||
create_door(player, 'Thieves BK Corner NE', Nrml).dir(No, 0xcc, Right, High).big_key().pos(0),
|
create_door(player, 'Thieves BK Corner NE', Nrml).dir(No, 0xcc, Right, High).big_key().pos(0),
|
||||||
create_door(player, 'Thieves Compass Room NW Edge', Open).dir(No, 0xdc, None, Low),
|
create_door(player, 'Thieves Compass Room NW Edge', Open).dir(No, 0xdc, None, Low).edge(9, A, 0x18),
|
||||||
create_door(player, 'Thieves Compass Room N Edge', Open).dir(No, 0xdc, None, Low),
|
create_door(player, 'Thieves Compass Room N Edge', Open).dir(No, 0xdc, None, Low).edge(10, A, 0x10),
|
||||||
create_door(player, 'Thieves Compass Room WS Edge', Open).dir(We, 0xdc, None, Low),
|
create_door(player, 'Thieves Compass Room WS Edge', Open).dir(We, 0xdc, None, Low).edge(8, Z, 0x50),
|
||||||
create_door(player, 'Thieves Compass Room W', Nrml).dir(We, 0xdc, Mid, High).pos(0),
|
create_door(player, 'Thieves Compass Room W', Nrml).dir(We, 0xdc, Mid, High).pos(0),
|
||||||
create_door(player, 'Thieves Hallway SE', Nrml).dir(So, 0xbc, Right, High).small_key().pos(1),
|
create_door(player, 'Thieves Hallway SE', Nrml).dir(So, 0xbc, Right, High).small_key().pos(1),
|
||||||
create_door(player, 'Thieves Hallway NE', Nrml).dir(No, 0xbc, Right, High).pos(7),
|
create_door(player, 'Thieves Hallway NE', Nrml).dir(No, 0xbc, Right, High).pos(7),
|
||||||
@@ -589,8 +589,8 @@ def create_doors(world, player):
|
|||||||
create_door(player, 'Thieves Attic Down Stairs', Sprl).dir(Dn, 0x64, 0, HTH).ss(Z, 0x11, 0x80, True, True),
|
create_door(player, 'Thieves Attic Down Stairs', Sprl).dir(Dn, 0x64, 0, HTH).ss(Z, 0x11, 0x80, True, True),
|
||||||
create_door(player, 'Thieves Attic ES', Intr).dir(Ea, 0x64, Bot, High).pos(0),
|
create_door(player, 'Thieves Attic ES', Intr).dir(Ea, 0x64, Bot, High).pos(0),
|
||||||
create_door(player, 'Thieves Cricket Hall Left WS', Intr).dir(We, 0x64, Bot, High).pos(0),
|
create_door(player, 'Thieves Cricket Hall Left WS', Intr).dir(We, 0x64, Bot, High).pos(0),
|
||||||
create_door(player, 'Thieves Cricket Hall Left Edge', Open).dir(Ea, 0x64, None, High),
|
create_door(player, 'Thieves Cricket Hall Left Edge', Open).dir(Ea, 0x64, None, High).edge(0, X, 0x30),
|
||||||
create_door(player, 'Thieves Cricket Hall Right Edge', Open).dir(We, 0x65, None, High),
|
create_door(player, 'Thieves Cricket Hall Right Edge', Open).dir(We, 0x65, None, High).edge(0, Z, 0x30),
|
||||||
create_door(player, 'Thieves Cricket Hall Right ES', Intr).dir(Ea, 0x65, Bot, High).pos(0),
|
create_door(player, 'Thieves Cricket Hall Right ES', Intr).dir(Ea, 0x65, Bot, High).pos(0),
|
||||||
create_door(player, 'Thieves Attic Window WS', Intr).dir(We, 0x65, Bot, High).pos(0),
|
create_door(player, 'Thieves Attic Window WS', Intr).dir(We, 0x65, Bot, High).pos(0),
|
||||||
create_door(player, 'Thieves Basement Block Up Stairs', Sprl).dir(Up, 0x45, 0, HTH).ss(A, 0x1a, 0x6c, True, True),
|
create_door(player, 'Thieves Basement Block Up Stairs', Sprl).dir(Up, 0x45, 0, HTH).ss(A, 0x1a, 0x6c, True, True),
|
||||||
@@ -1231,7 +1231,7 @@ def create_paired_doors(world, player):
|
|||||||
PairedDoor('PoD Falling Bridge WN', 'PoD Dark Maze EN', True), # Pod Dark maze door
|
PairedDoor('PoD Falling Bridge WN', 'PoD Dark Maze EN', True), # Pod Dark maze door
|
||||||
PairedDoor('PoD Dark Maze E', 'PoD Big Chest Balcony W', True), # PoD Bombable by Big Chest
|
PairedDoor('PoD Dark Maze E', 'PoD Big Chest Balcony W', True), # PoD Bombable by Big Chest
|
||||||
PairedDoor('PoD Arena Main NW', 'PoD Falling Bridge SW', True), # Pod key door by bridge
|
PairedDoor('PoD Arena Main NW', 'PoD Falling Bridge SW', True), # Pod key door by bridge
|
||||||
PairedDoor('Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S', True),
|
PairedDoor('Sewers Dark Cross Key Door N', 'Sewers Water S', True),
|
||||||
PairedDoor('Swamp Hub WN', 'Swamp Crystal Switch EN', True), # Swamp key door crystal switch
|
PairedDoor('Swamp Hub WN', 'Swamp Crystal Switch EN', True), # Swamp key door crystal switch
|
||||||
PairedDoor('Swamp Hub North Ledge N', 'Swamp Push Statue S', True), # Swamp key door above big chest
|
PairedDoor('Swamp Hub North Ledge N', 'Swamp Push Statue S', True), # Swamp key door above big chest
|
||||||
PairedDoor('PoD Map Balcony WS', 'PoD Arena Ledge ES', True), # Pod bombable by arena
|
PairedDoor('PoD Map Balcony WS', 'PoD Arena Ledge ES', True), # Pod bombable by arena
|
||||||
|
|||||||
@@ -520,6 +520,10 @@ type_map = {
|
|||||||
Hook.South: Hook.North,
|
Hook.South: Hook.North,
|
||||||
Hook.West: Hook.East,
|
Hook.West: Hook.East,
|
||||||
Hook.East: Hook.West,
|
Hook.East: Hook.West,
|
||||||
|
Hook.NEdge: Hook.SEdge,
|
||||||
|
Hook.SEdge: Hook.NEdge,
|
||||||
|
Hook.EEdge: Hook.WEdge,
|
||||||
|
Hook.WEdge: Hook.EEdge,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -535,21 +539,31 @@ hang_dir_map = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
edge_map_back = {
|
||||||
|
Direction.North: Hook.SEdge,
|
||||||
|
Direction.South: Hook.NEdge,
|
||||||
|
Direction.West: Hook.EEdge,
|
||||||
|
Direction.East: Hook.WEdge,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def hanger_from_door(door):
|
def hanger_from_door(door):
|
||||||
if door.type == DoorType.SpiralStairs:
|
if door.type == DoorType.SpiralStairs:
|
||||||
return Hook.Stairs
|
return Hook.Stairs
|
||||||
if door.type == DoorType.Normal:
|
if door.type == DoorType.Normal:
|
||||||
return hang_dir_map[door.direction]
|
return hang_dir_map[door.direction]
|
||||||
|
if door.type == DoorType.Open:
|
||||||
|
return edge_map_back[door.direction]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def connect_doors(a, b):
|
def connect_doors(a, b):
|
||||||
# Return on unsupported types.
|
# Return on unsupported types.
|
||||||
if a.type in [DoorType.Open, DoorType.StraightStairs, DoorType.Hole, DoorType.Warp, DoorType.Ladder,
|
if a.type in [DoorType.StraightStairs, DoorType.Hole, DoorType.Warp, DoorType.Ladder,
|
||||||
DoorType.Interior, DoorType.Logical]:
|
DoorType.Interior, DoorType.Logical]:
|
||||||
return
|
return
|
||||||
# Connect supported types
|
# Connect supported types
|
||||||
if a.type == DoorType.Normal or a.type == DoorType.SpiralStairs:
|
if a.type == DoorType.Normal or a.type == DoorType.SpiralStairs or a.type == DoorType.Open:
|
||||||
if a.blocked:
|
if a.blocked:
|
||||||
connect_one_way(b.entrance, a.entrance)
|
connect_one_way(b.entrance, a.entrance)
|
||||||
elif b.blocked:
|
elif b.blocked:
|
||||||
@@ -798,6 +812,8 @@ class ExplorationState(object):
|
|||||||
def add_all_doors_check_keys(self, region, key_door_proposal, world, player):
|
def add_all_doors_check_keys(self, region, key_door_proposal, world, player):
|
||||||
for door in get_doors(world, region, player):
|
for door in get_doors(world, region, player):
|
||||||
if self.can_traverse(door):
|
if self.can_traverse(door):
|
||||||
|
if door.controller:
|
||||||
|
door = door.controller
|
||||||
if door in key_door_proposal and door not in self.opened_doors:
|
if door in key_door_proposal and door not in self.opened_doors:
|
||||||
if not self.in_door_list(door, self.small_doors):
|
if not self.in_door_list(door, self.small_doors):
|
||||||
self.append_door_to_list(door, self.small_doors)
|
self.append_door_to_list(door, self.small_doors)
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ def fill_dungeons_restrictive(world, shuffled_locations):
|
|||||||
# with shuffled dungeon items they are distributed as part of the normal item pool
|
# with shuffled dungeon items they are distributed as part of the normal item pool
|
||||||
for item in world.get_items():
|
for item in world.get_items():
|
||||||
if (item.smallkey and world.keyshuffle[item.player]) or (item.bigkey and world.bigkeyshuffle[item.player]):
|
if (item.smallkey and world.keyshuffle[item.player]) or (item.bigkey and world.bigkeyshuffle[item.player]):
|
||||||
all_state_base.collect(item, True)
|
|
||||||
item.advancement = True
|
item.advancement = True
|
||||||
elif (item.map and world.mapshuffle[item.player]) or (item.compass and world.compassshuffle[item.player]):
|
elif (item.map and world.mapshuffle[item.player]) or (item.compass and world.compassshuffle[item.player]):
|
||||||
item.priority = True
|
item.priority = True
|
||||||
@@ -146,7 +145,8 @@ def fill_dungeons_restrictive(world, shuffled_locations):
|
|||||||
sort_order = {"BigKey": 3, "SmallKey": 2}
|
sort_order = {"BigKey": 3, "SmallKey": 2}
|
||||||
dungeon_items.sort(key=lambda item: sort_order.get(item.type, 1))
|
dungeon_items.sort(key=lambda item: sort_order.get(item.type, 1))
|
||||||
|
|
||||||
fill_restrictive(world, all_state_base, shuffled_locations, dungeon_items, True)
|
fill_restrictive(world, all_state_base, shuffled_locations, dungeon_items,
|
||||||
|
keys_in_itempool={player: not world.keyshuffle[player] for player in range(1, world.players+1)}, single_player_placement=True)
|
||||||
|
|
||||||
|
|
||||||
dungeon_music_addresses = {'Eastern Palace - Prize': [0x1559A],
|
dungeon_music_addresses = {'Eastern Palace - Prize': [0x1559A],
|
||||||
|
|||||||
7
Fill.py
7
Fill.py
@@ -161,7 +161,7 @@ def distribute_items_staleness(world):
|
|||||||
logging.getLogger('').debug('Unplaced items: %s - Unfilled Locations: %s', [item.name for item in itempool], [location.name for location in fill_locations])
|
logging.getLogger('').debug('Unplaced items: %s - Unfilled Locations: %s', [item.name for item in itempool], [location.name for location in fill_locations])
|
||||||
|
|
||||||
|
|
||||||
def fill_restrictive(world, base_state, locations, itempool, single_player_placement = False):
|
def fill_restrictive(world, base_state, locations, itempool, keys_in_itempool = None, single_player_placement = False):
|
||||||
def sweep_from_pool():
|
def sweep_from_pool():
|
||||||
new_state = base_state.copy()
|
new_state = base_state.copy()
|
||||||
for item in itempool:
|
for item in itempool:
|
||||||
@@ -202,7 +202,7 @@ def fill_restrictive(world, base_state, locations, itempool, single_player_place
|
|||||||
test_state = maximum_exploration_state
|
test_state = maximum_exploration_state
|
||||||
if (not single_player_placement or location.player == item_to_place.player)\
|
if (not single_player_placement or location.player == item_to_place.player)\
|
||||||
and location.can_fill(test_state, item_to_place, perform_access_check)\
|
and location.can_fill(test_state, item_to_place, perform_access_check)\
|
||||||
and valid_key_placement(item_to_place, location, itempool, world):
|
and valid_key_placement(item_to_place, location, itempool if (keys_in_itempool and keys_in_itempool[item_to_place.player]) else world.itempool, world):
|
||||||
spot_to_fill = location
|
spot_to_fill = location
|
||||||
break
|
break
|
||||||
elif item_to_place.smallkey or item_to_place.bigkey:
|
elif item_to_place.smallkey or item_to_place.bigkey:
|
||||||
@@ -290,7 +290,8 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||||||
# todo: crossed
|
# todo: crossed
|
||||||
progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' and world.keyshuffle[item.player] and world.mode[item.player] == 'standard' else 0)
|
progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' and world.keyshuffle[item.player] and world.mode[item.player] == 'standard' else 0)
|
||||||
|
|
||||||
fill_restrictive(world, world.state, fill_locations, progitempool)
|
fill_restrictive(world, world.state, fill_locations, progitempool,
|
||||||
|
keys_in_itempool={player: world.keyshuffle[player] for player in range(1, world.players+1)})
|
||||||
|
|
||||||
random.shuffle(fill_locations)
|
random.shuffle(fill_locations)
|
||||||
|
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ def fill_prizes(world, attempts=15):
|
|||||||
prize_locs = list(empty_crystal_locations)
|
prize_locs = list(empty_crystal_locations)
|
||||||
random.shuffle(prizepool)
|
random.shuffle(prizepool)
|
||||||
random.shuffle(prize_locs)
|
random.shuffle(prize_locs)
|
||||||
fill_restrictive(world, all_state, prize_locs, prizepool, True)
|
fill_restrictive(world, all_state, prize_locs, prizepool, single_player_placement=True)
|
||||||
except FillError as e:
|
except FillError as e:
|
||||||
logging.getLogger('').info("Failed to place dungeon prizes (%s). Will retry %s more times", e, attempts - attempt - 1)
|
logging.getLogger('').info("Failed to place dungeon prizes (%s). Will retry %s more times", e, attempts - attempt - 1)
|
||||||
for location in empty_crystal_locations:
|
for location in empty_crystal_locations:
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'Sewers Behind Tapestry', 'Hyrule Castle', None, ['Sewers Behind Tapestry S', 'Sewers Behind Tapestry Down Stairs']),
|
create_dungeon_region(player, 'Sewers Behind Tapestry', 'Hyrule Castle', None, ['Sewers Behind Tapestry S', 'Sewers Behind Tapestry Down Stairs']),
|
||||||
create_dungeon_region(player, 'Sewers Rope Room', 'Hyrule Castle', None, ['Sewers Rope Room Up Stairs', 'Sewers Rope Room North Stairs']),
|
create_dungeon_region(player, 'Sewers Rope Room', 'Hyrule Castle', None, ['Sewers Rope Room Up Stairs', 'Sewers Rope Room North Stairs']),
|
||||||
create_dungeon_region(player, 'Sewers Dark Cross', 'Hyrule Castle', ['Sewers - Dark Cross'], ['Sewers Dark Cross Key Door N', 'Sewers Dark Cross South Stairs']),
|
create_dungeon_region(player, 'Sewers Dark Cross', 'Hyrule Castle', ['Sewers - Dark Cross'], ['Sewers Dark Cross Key Door N', 'Sewers Dark Cross South Stairs']),
|
||||||
create_dungeon_region(player, 'Sewers Water', 'Hyrule Castle', None, ['Sewers Dark Cross Key Door S', 'Sewers Water W']),
|
create_dungeon_region(player, 'Sewers Water', 'Hyrule Castle', None, ['Sewers Water S', 'Sewers Water W']),
|
||||||
create_dungeon_region(player, 'Sewers Key Rat', 'Hyrule Castle', ['Hyrule Castle - Key Rat Key Drop'], ['Sewers Key Rat E', 'Sewers Key Rat Key Door N']),
|
create_dungeon_region(player, 'Sewers Key Rat', 'Hyrule Castle', ['Hyrule Castle - Key Rat Key Drop'], ['Sewers Key Rat E', 'Sewers Key Rat Key Door N']),
|
||||||
create_dungeon_region(player, 'Sewers Secret Room Blocked Path', 'Hyrule Castle', None, ['Sewers Secret Room Up Stairs']),
|
create_dungeon_region(player, 'Sewers Secret Room Blocked Path', 'Hyrule Castle', None, ['Sewers Secret Room Up Stairs']),
|
||||||
create_dungeon_region(player, 'Sewers Rat Path', 'Hyrule Castle', None, ['Sewers Secret Room Key Door S', 'Sewers Secret Room Push Block', 'Sewers Rat Path WS', 'Sewers Rat Path WN']),
|
create_dungeon_region(player, 'Sewers Rat Path', 'Hyrule Castle', None, ['Sewers Secret Room Key Door S', 'Sewers Secret Room Push Block', 'Sewers Rat Path WS', 'Sewers Rat Path WN']),
|
||||||
@@ -460,7 +460,7 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'Thieves Rail Ledge', 'Thieves\' Town', None, ['Thieves Rail Ledge NW', 'Thieves Rail Ledge W', 'Thieves Rail Ledge Drop Down']),
|
create_dungeon_region(player, 'Thieves Rail Ledge', 'Thieves\' Town', None, ['Thieves Rail Ledge NW', 'Thieves Rail Ledge W', 'Thieves Rail Ledge Drop Down']),
|
||||||
create_dungeon_region(player, 'Thieves BK Corner', 'Thieves\' Town', None, ['Thieves BK Corner WN Edge', 'Thieves BK Corner WS Edge', 'Thieves BK Corner S Edge', 'Thieves BK Corner SW Edge', 'Thieves BK Corner NE']),
|
create_dungeon_region(player, 'Thieves BK Corner', 'Thieves\' Town', None, ['Thieves BK Corner WN Edge', 'Thieves BK Corner WS Edge', 'Thieves BK Corner S Edge', 'Thieves BK Corner SW Edge', 'Thieves BK Corner NE']),
|
||||||
create_dungeon_region(player, 'Thieves Compass Room', 'Thieves\' Town', ['Thieves\' Town - Compass Chest'], ['Thieves Compass Room NW Edge', 'Thieves Compass Room N Edge', 'Thieves Compass Room WS Edge', 'Thieves Compass Room W']),
|
create_dungeon_region(player, 'Thieves Compass Room', 'Thieves\' Town', ['Thieves\' Town - Compass Chest'], ['Thieves Compass Room NW Edge', 'Thieves Compass Room N Edge', 'Thieves Compass Room WS Edge', 'Thieves Compass Room W']),
|
||||||
create_dungeon_region(player, 'Thieves Big Chest Nook', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest'], ['Thieves Big Chest Nook WS Edge']),
|
create_dungeon_region(player, 'Thieves Big Chest Nook', 'Thieves\' Town', ['Thieves\' Town - Big Key Chest'], ['Thieves Big Chest Nook ES Edge']),
|
||||||
create_dungeon_region(player, 'Thieves Hallway', 'Thieves\' Town', ['Thieves\' Town - Hallway Pot Key'], ['Thieves Hallway SE', 'Thieves Hallway NE', 'Thieves Hallway WN', 'Thieves Hallway WS']),
|
create_dungeon_region(player, 'Thieves Hallway', 'Thieves\' Town', ['Thieves\' Town - Hallway Pot Key'], ['Thieves Hallway SE', 'Thieves Hallway NE', 'Thieves Hallway WN', 'Thieves Hallway WS']),
|
||||||
create_dungeon_region(player, 'Thieves Boss', 'Thieves\' Town', ['Revealing Light', 'Thieves\' Town - Boss', 'Thieves\' Town - Prize'], ['Thieves Boss SE']),
|
create_dungeon_region(player, 'Thieves Boss', 'Thieves\' Town', ['Revealing Light', 'Thieves\' Town - Boss', 'Thieves\' Town - Prize'], ['Thieves Boss SE']),
|
||||||
create_dungeon_region(player, 'Thieves Pot Alcove Mid', 'Thieves\' Town', None, ['Thieves Pot Alcove Mid ES', 'Thieves Pot Alcove Mid WS']),
|
create_dungeon_region(player, 'Thieves Pot Alcove Mid', 'Thieves\' Town', None, ['Thieves Pot Alcove Mid ES', 'Thieves Pot Alcove Mid WS']),
|
||||||
|
|||||||
6
Rom.py
6
Rom.py
@@ -605,7 +605,7 @@ def patch_rom(world, rom, player, team, enemized):
|
|||||||
rom.write_byte(0x139004, 1)
|
rom.write_byte(0x139004, 1)
|
||||||
for door in world.doors:
|
for door in world.doors:
|
||||||
if door.dest is not None and door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs]:
|
if door.dest is not None and door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs]:
|
||||||
rom.write_bytes(door.getAddress(), door.dest.getTarget(door.toggle))
|
rom.write_bytes(door.getAddress(), door.dest.getTarget(door))
|
||||||
for room in world.rooms:
|
for room in world.rooms:
|
||||||
if room.player == player and room.modified:
|
if room.player == player and room.modified:
|
||||||
rom.write_bytes(room.address(), room.rom_data())
|
rom.write_bytes(room.address(), room.rom_data())
|
||||||
@@ -899,7 +899,7 @@ def patch_rom(world, rom, player, team, enemized):
|
|||||||
ERtimeincrease = 20
|
ERtimeincrease = 20
|
||||||
if world.keyshuffle[player] or world.bigkeyshuffle[player] or world.mapshuffle[player]:
|
if world.keyshuffle[player] or world.bigkeyshuffle[player] or world.mapshuffle[player]:
|
||||||
ERtimeincrease = ERtimeincrease + 15
|
ERtimeincrease = ERtimeincrease + 15
|
||||||
if world.clock_mode == 'off':
|
if world.clock_mode == 'none':
|
||||||
rom.write_bytes(0x180190, [0x00, 0x00, 0x00]) # turn off clock mode
|
rom.write_bytes(0x180190, [0x00, 0x00, 0x00]) # turn off clock mode
|
||||||
write_int32(rom, 0x180200, 0) # red clock adjustment time (in frames, sint32)
|
write_int32(rom, 0x180200, 0) # red clock adjustment time (in frames, sint32)
|
||||||
write_int32(rom, 0x180204, 0) # blue clock adjustment time (in frames, sint32)
|
write_int32(rom, 0x180204, 0) # blue clock adjustment time (in frames, sint32)
|
||||||
@@ -1157,7 +1157,7 @@ def patch_rom(world, rom, player, team, enemized):
|
|||||||
rom.write_byte(0x18003B, 0x01 if world.mapshuffle[player] else 0x00) # maps showing crystals on overworld
|
rom.write_byte(0x18003B, 0x01 if world.mapshuffle[player] else 0x00) # maps showing crystals on overworld
|
||||||
|
|
||||||
# compasses showing dungeon count
|
# compasses showing dungeon count
|
||||||
if world.clock_mode != 'off' or world.dungeon_counters[player] == 'off':
|
if world.clock_mode != 'none' or world.dungeon_counters[player] == 'off':
|
||||||
rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location
|
rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location
|
||||||
elif world.dungeon_counters[player] == 'on':
|
elif world.dungeon_counters[player] == 'on':
|
||||||
rom.write_byte(0x18003C, 0x02) # always on
|
rom.write_byte(0x18003C, 0x02) # always on
|
||||||
|
|||||||
2
Rules.py
2
Rules.py
@@ -732,7 +732,7 @@ def no_glitches_rules(world, player):
|
|||||||
'Sewers Dark Cross': {'sewer': True, 'entrances': ['Sewers Dark Cross Key Door N', 'Sewers Dark Cross South Stairs'], 'locations': ['Sewers - Dark Cross']},
|
'Sewers Dark Cross': {'sewer': True, 'entrances': ['Sewers Dark Cross Key Door N', 'Sewers Dark Cross South Stairs'], 'locations': ['Sewers - Dark Cross']},
|
||||||
'Sewers Behind Tapestry': {'sewer': True, 'entrances': ['Sewers Behind Tapestry S', 'Sewers Behind Tapestry Down Stairs'], 'locations': []},
|
'Sewers Behind Tapestry': {'sewer': True, 'entrances': ['Sewers Behind Tapestry S', 'Sewers Behind Tapestry Down Stairs'], 'locations': []},
|
||||||
'Sewers Rope Room': {'sewer': True, 'entrances': ['Sewers Rope Room Up Stairs', 'Sewers Rope Room North Stairs'], 'locations': []},
|
'Sewers Rope Room': {'sewer': True, 'entrances': ['Sewers Rope Room Up Stairs', 'Sewers Rope Room North Stairs'], 'locations': []},
|
||||||
'Sewers Water': {'sewer': True, 'entrances': ['Sewers Dark Cross Key Door S', 'Sewers Water W'], 'locations': []},
|
'Sewers Water': {'sewer': True, 'entrances': ['Sewers Water S', 'Sewers Water W'], 'locations': []},
|
||||||
'Sewers Key Rat': {'sewer': True, 'entrances': ['Sewers Key Rat E', 'Sewers Key Rat Key Door N'], 'locations': ['Hyrule Castle - Key Rat Key Drop']},
|
'Sewers Key Rat': {'sewer': True, 'entrances': ['Sewers Key Rat E', 'Sewers Key Rat Key Door N'], 'locations': ['Hyrule Castle - Key Rat Key Drop']},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
Tables.py
21
Tables.py
@@ -60,3 +60,24 @@ door_pair_offset_table = {
|
|||||||
0xc9: 0x01e7, 0xcb: 0x01ec, 0xcc: 0x01ed, 0xce: 0x01f0, 0xd0: 0x01f1, 0xd1: 0x01f3, 0xd2: 0x01f7, 0xd5: 0x01f8,
|
0xc9: 0x01e7, 0xcb: 0x01ec, 0xcc: 0x01ed, 0xce: 0x01f0, 0xd0: 0x01f1, 0xd1: 0x01f3, 0xd2: 0x01f7, 0xd5: 0x01f8,
|
||||||
0xd6: 0x01fa, 0xd8: 0x01fd, 0xd9: 0x0200, 0xda: 0x0203, 0xdb: 0x0204, 0xdc: 0x0206, 0xe0: 0x020
|
0xd6: 0x01fa, 0xd8: 0x01fd, 0xd9: 0x0200, 0xda: 0x0203, 0xdb: 0x0204, 0xdc: 0x0206, 0xe0: 0x020
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multiply_lookup = {
|
||||||
|
0x08: {0x8: 1, 0x10: 2, 0x18: 3, 0x20: 4, 0x30: 6, 0x50: 0xa, 0xa0: 0x14},
|
||||||
|
0x10: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 2, 0x30: 3, 0x50: 0x4, 0xa0: 0xa},
|
||||||
|
0x18: {0x8: 1, 0x10: 2, 0x18: 1, 0x20: 4, 0x30: 2, 0x50: 0xa, 0xa0: 0x14},
|
||||||
|
0x20: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 1, 0x30: 3, 0x50: 5, 0xa0: 5},
|
||||||
|
0x30: {0x8: 1, 0x10: 1, 0x18: 1, 0x20: 2, 0x30: 1, 0x50: 5, 0xa0: 0xa},
|
||||||
|
0x50: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 2, 0x30: 3, 0x50: 1, 0xa0: 2},
|
||||||
|
0xa0: {0x8: 1, 0x10: 1, 0x18: 3, 0x20: 1, 0x30: 3, 0x50: 1, 0xa0: 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
divisor_lookup = {
|
||||||
|
0x08: {0x8: 1, 0x10: 1, 0x18: 1, 0x20: 1, 0x30: 1, 0x50: 1, 0xa0: 1},
|
||||||
|
0x10: {0x8: 2, 0x10: 1, 0x18: 2, 0x20: 1, 0x30: 1, 0x50: 1, 0xa0: 1},
|
||||||
|
0x18: {0x8: 3, 0x10: 3, 0x18: 1, 0x20: 3, 0x30: 1, 0x50: 3, 0xa0: 3},
|
||||||
|
0x20: {0x8: 4, 0x10: 2, 0x18: 4, 0x20: 1, 0x30: 2, 0x50: 2, 0xa0: 1},
|
||||||
|
0x30: {0x8: 6, 0x10: 3, 0x18: 2, 0x20: 3, 0x30: 1, 0x50: 3, 0xa0: 3},
|
||||||
|
0x50: {0x8: 0xa, 0x10: 4, 0x18: 0xa, 0x20: 5, 0x30: 5, 0x50: 1, 0xa0: 1},
|
||||||
|
0xa0: {0x8: 0x14, 0x10: 0xa, 0x18: 0x14, 0x20: 5, 0x30: 0xa, 0x50: 2, 0xa0: 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
41
Utils.py
41
Utils.py
@@ -3,6 +3,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
def int16_as_bytes(value):
|
def int16_as_bytes(value):
|
||||||
value = value & 0xFFFF
|
value = value & 0xFFFF
|
||||||
@@ -239,6 +240,46 @@ def print_wiki_doors(d_regions, world, player):
|
|||||||
print('|}')
|
print('|}')
|
||||||
|
|
||||||
|
|
||||||
|
def print_xml_doors(d_regions, world, player):
|
||||||
|
root = ET.Element('root')
|
||||||
|
for d, region_list in d_regions.items():
|
||||||
|
tile_map = {}
|
||||||
|
for region in region_list:
|
||||||
|
tile = None
|
||||||
|
r = world.get_region(region, player)
|
||||||
|
for ext in r.exits:
|
||||||
|
door = world.check_for_door(ext.name, player)
|
||||||
|
if door is not None and door.roomIndex != -1:
|
||||||
|
tile = door.roomIndex
|
||||||
|
break
|
||||||
|
if tile is not None:
|
||||||
|
if tile not in tile_map:
|
||||||
|
tile_map[tile] = []
|
||||||
|
tile_map[tile].append(r)
|
||||||
|
dungeon = ET.SubElement(root, 'dungeon', {'name': d})
|
||||||
|
for tile, r_list in tile_map.items():
|
||||||
|
supertile = ET.SubElement(dungeon, 'supertile', {'id': str(tile)})
|
||||||
|
for region in r_list:
|
||||||
|
room = ET.SubElement(supertile, 'room', {'name': region.name})
|
||||||
|
for ext in region.exits:
|
||||||
|
ET.SubElement(room, 'door', {'name': ext.name})
|
||||||
|
ET.dump(root)
|
||||||
|
|
||||||
|
|
||||||
|
def print_graph(world):
|
||||||
|
root = ET.Element('root')
|
||||||
|
for region in world.regions:
|
||||||
|
r = ET.SubElement(root, 'region', {'name': region.name})
|
||||||
|
for ext in region.exits:
|
||||||
|
attribs = {'name': ext.name}
|
||||||
|
if ext.connected_region:
|
||||||
|
attribs['connected_region'] = ext.connected_region.name
|
||||||
|
if ext.door and ext.door.dest:
|
||||||
|
attribs['dest'] = ext.door.dest.name
|
||||||
|
ET.SubElement(r, 'exit', attribs)
|
||||||
|
ET.dump(root)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pass
|
pass
|
||||||
# make_new_base2current()
|
# make_new_base2current()
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
!add = "clc : adc"
|
!add = "clc : adc"
|
||||||
!sub = "sec : sbc"
|
!sub = "sec : sbc"
|
||||||
|
!bge = "bcs"
|
||||||
|
!blt = "bcc"
|
||||||
|
|
||||||
; Free RAM notes
|
; Free RAM notes
|
||||||
; Normal doors use $FE for scrolling indicator
|
; Normal doors use $AB-AC for scrolling indicator
|
||||||
; Normal doors use $AB to store the trap door indicator
|
; Normal doors use $FE to store the trap door indicator
|
||||||
; Spiral doors use $045e to store stair type
|
; Spiral doors use $045e to store stair type
|
||||||
; Gfx uses $b1 to for sub-sub-sub-module thing
|
; Gfx uses $b1 to for sub-sub-sub-module thing
|
||||||
|
|
||||||
@@ -17,6 +19,8 @@ incsrc spiral.asm
|
|||||||
incsrc gfx.asm
|
incsrc gfx.asm
|
||||||
incsrc keydoors.asm
|
incsrc keydoors.asm
|
||||||
incsrc overrides.asm
|
incsrc overrides.asm
|
||||||
|
;incsrc edges.asm
|
||||||
|
;incsrc math.asm
|
||||||
warnpc $279000
|
warnpc $279000
|
||||||
|
|
||||||
; Data Section
|
; Data Section
|
||||||
|
|||||||
@@ -489,3 +489,55 @@ dw $0000,$0000
|
|||||||
dw $0000
|
dw $0000
|
||||||
dw $0000,$0000,$0000,$0000
|
dw $0000,$0000,$0000,$0000
|
||||||
dw $ffff ; indicates the end - we can drop this
|
dw $ffff ; indicates the end - we can drop this
|
||||||
|
|
||||||
|
; Edge Transition Table
|
||||||
|
org $27C500 ;ends around 27C5F0
|
||||||
|
NorthOpenEdge:
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
SouthOpenEdge:
|
||||||
|
db $83,$a2,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
WestOpenEdge:
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
EastOpenEdge:
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
db $00,$80,$11, $00,$80,$11, $00,$80,$11
|
||||||
|
; Edge Info Table (Midpoint, Width, Min Coord)
|
||||||
|
NorthEdgeInfo:
|
||||||
|
db $a8,$10,$a0, $2c,$08,$28 ;HC
|
||||||
|
db $b8,$20,$a8 ; DP West Wing
|
||||||
|
db $38,$20,$28, $f8,$a0,$a8, $b8,$20,$a8 ; DP Main
|
||||||
|
db $78,$20,$68 ; DP East Wing
|
||||||
|
db $f8,$10,$f0, $7c,$18,$70 ; TT Lobby
|
||||||
|
db $74,$18,$68, $f8,$10,$f0 ; TT Compass
|
||||||
|
SouthEdgeInfo:
|
||||||
|
db $a8,$10,$a0, $2c,$08,$28 ; HC
|
||||||
|
db $b8,$20,$a8 ; DP Sandworm
|
||||||
|
db $38,$20,$28, $f8,$a0,$a8, $b8,$20,$a8 ; DP North Hall & Dead End
|
||||||
|
db $78,$20,$68 ; DP Arrow Pot
|
||||||
|
db $f8,$10,$f0, $7c,$18,$70 ; TT Ambush
|
||||||
|
db $74,$18,$68, $f8,$10,$f0 ; TT BK Corner
|
||||||
|
WestEdgeInfo:
|
||||||
|
db $78,$30,$60 ; TT Attic
|
||||||
|
db $40,$20,$30 ; DP North Hall
|
||||||
|
db $40,$20,$30 ; DP Arrow Pot
|
||||||
|
db $84,$18,$78, $68,$10,$60 ; HC South
|
||||||
|
db $a0,$a0,$50 ; DP East Wing
|
||||||
|
db $58,$50,$30, $98,$50,$70 ; TT BK Corner
|
||||||
|
db $58,$50,$30 ; TT Compass
|
||||||
|
EastEdgeInfo:
|
||||||
|
db $78,$30,$60 ; TT Attic
|
||||||
|
db $40,$20,$30 ; DP Sandworm
|
||||||
|
db $40,$20,$30 ; DP North Hall
|
||||||
|
db $68,$10,$60, $84,$18,$78 ; HC Guards
|
||||||
|
db $a0,$a0,$50 ; DP Main Lobby
|
||||||
|
db $58,$50,$30, $98,$50,$70 ; TT Ambush
|
||||||
|
db $58,$50,$30 ; TT Nook
|
||||||
|
MultDivInfo: ; (1placeholder, 1, 2, 3, 4, 5, 6, 10, 20)
|
||||||
|
db $01, $01, $02, $03, $04, $05, $06, $0a, $14
|
||||||
291
asm/edges.asm
Normal file
291
asm/edges.asm
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
HorzEdge:
|
||||||
|
cpy #$ff : beq +
|
||||||
|
jsr DetectWestEdge : bra ++
|
||||||
|
+ jsr DetectEastEdge
|
||||||
|
++ cmp #$ff : beq +
|
||||||
|
sta $00 : asl : !add $00 : tax
|
||||||
|
cpy #$ff : beq ++
|
||||||
|
jsr LoadWestData : bra .main
|
||||||
|
++ jsr LoadEastData
|
||||||
|
.main
|
||||||
|
jsr LoadEdgeRoomHorz
|
||||||
|
sec : rts
|
||||||
|
+ clc : rts
|
||||||
|
|
||||||
|
VertEdge:
|
||||||
|
cpy #$ff : beq +
|
||||||
|
jsr DetectNorthEdge : bra ++
|
||||||
|
+ jsr DetectSouthEdge
|
||||||
|
++ cmp #$ff : beq +
|
||||||
|
sta $00 : asl : !add $00 : tax
|
||||||
|
cpy #$ff : beq ++
|
||||||
|
jsr LoadNorthData : bra .main
|
||||||
|
++ jsr LoadSouthData
|
||||||
|
.main
|
||||||
|
jsr LoadEdgeRoomVert
|
||||||
|
sec : rts
|
||||||
|
+ clc : rts
|
||||||
|
|
||||||
|
LoadEdgeRoomHorz:
|
||||||
|
lda $03 : sta $a0
|
||||||
|
sty $09
|
||||||
|
and.b #$0f : asl a : !sub $23 : !add $09 : sta $02
|
||||||
|
ldy #$00 : jsr ShiftVariablesMainDir
|
||||||
|
lda $a0 : and.b #$F0 : lsr #3 : sta $0603 : inc : sta $0607
|
||||||
|
|
||||||
|
|
||||||
|
lda $aa : asl : tax ; current quad as 0/4
|
||||||
|
lda $04 : and #$40 : bne +
|
||||||
|
lda $603 : sta $00 : stz $01 : bra ++
|
||||||
|
+ lda $607 : sta $00 : lda #$02 : sta $01
|
||||||
|
++ ; $01 now contains 0 or 2
|
||||||
|
lda $00 : sta $21 : sta $0601 : sta $0605
|
||||||
|
lda $01 : sta $aa : lsr : sta $01 : stz $00
|
||||||
|
lda $0a : sta $20
|
||||||
|
|
||||||
|
stz $0e
|
||||||
|
rep #$30
|
||||||
|
lda $e8 : and #$01ff : sta $02
|
||||||
|
lda $0a : and #$00ff : !add $00 : sta $00
|
||||||
|
|
||||||
|
cmp #$006c : !bge +
|
||||||
|
lda #$0077 : bra ++
|
||||||
|
+ cmp #$017c : !blt +
|
||||||
|
lda #$0187 : bra ++
|
||||||
|
+ !add #$000b
|
||||||
|
++ sta $0618 : inc #2 : sta $061a
|
||||||
|
|
||||||
|
lda $00 : cmp #$0078 : !bge +
|
||||||
|
lda #$0000 : bra ++
|
||||||
|
+ cmp #$0178 : !blt +
|
||||||
|
lda #$0100 : bra ++
|
||||||
|
+ !sub #$0078
|
||||||
|
++ sta $00
|
||||||
|
|
||||||
|
; figures out scroll amt
|
||||||
|
cmp $02 : bne +
|
||||||
|
lda #$0000 : bra .done
|
||||||
|
+ !blt +
|
||||||
|
!sub $02 : inc $0e : bra .done
|
||||||
|
+ lda $02 : !sub $00
|
||||||
|
|
||||||
|
.done sta $ab : sep #$30
|
||||||
|
lda $0e : asl : ora $ac : sta $ac
|
||||||
|
lda $0603, x : sta $e9
|
||||||
|
|
||||||
|
lda $04 : and #$80 : lsr #4 : sta $ee ; layer stuff
|
||||||
|
rts
|
||||||
|
|
||||||
|
LoadEdgeRoomVert:
|
||||||
|
lda $03 : sta $a0
|
||||||
|
sty $09
|
||||||
|
and.b #$f0 : lsr #3 : !sub $21 : !add $09 : sta $02
|
||||||
|
ldy #$01 : jsr ShiftVariablesMainDir
|
||||||
|
lda $a0 : and.b #$0f : asl : sta $060b : inc : sta $060f
|
||||||
|
|
||||||
|
lda $a9 : asl #2 : tax ; current quad as 0/4
|
||||||
|
lda $04 : and #$20 : bne +
|
||||||
|
lda $60b : sta $00 : stz $01 : bra ++
|
||||||
|
+ lda $60f : sta $00 : lda #$01 : sta $01
|
||||||
|
++ ; $01 now contains 0 or 1
|
||||||
|
lda $00 : sta $23 : sta $0609 : sta $060d
|
||||||
|
lda $01 : sta $a9 : stz $00 ; setup for 16 bit ops
|
||||||
|
lda $0a : sta $22
|
||||||
|
|
||||||
|
stz $0e ; pos/neg indicator
|
||||||
|
rep #$30
|
||||||
|
lda $e2 : and #$01ff : sta $02
|
||||||
|
lda $0a : and #$00ff : !add $00 : sta $00
|
||||||
|
|
||||||
|
cmp #$0078 : !bge +
|
||||||
|
lda #$007f : bra ++
|
||||||
|
+ cmp #$0178 : !blt +
|
||||||
|
lda #$017f : bra ++
|
||||||
|
+ !add #$0007
|
||||||
|
++ sta $061c : inc #2 : sta $061e
|
||||||
|
|
||||||
|
lda $00 : cmp #$0078 : !bge +
|
||||||
|
lda #$0000 : bra ++
|
||||||
|
+ cmp #$0178 : !blt +
|
||||||
|
lda #$0100 : bra ++
|
||||||
|
+ !sub #$0078
|
||||||
|
++ sta $00
|
||||||
|
|
||||||
|
; figures out scroll amt
|
||||||
|
cmp $02 : bne +
|
||||||
|
lda #$0000 : bra .done
|
||||||
|
+ !blt +
|
||||||
|
!sub $02 : inc $0e : bra .done
|
||||||
|
+ lda $02 : !sub $00
|
||||||
|
|
||||||
|
.done sta $ab : sep #$30
|
||||||
|
lda $0e : asl : ora $ac : sta $ac
|
||||||
|
lda $060b, x : sta $e3
|
||||||
|
|
||||||
|
lda $04 : and #$10 : lsr #4 : sta $ee ; layer stuff
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
LoadNorthData:
|
||||||
|
lda NorthEdgeInfo, x : sta $06 ; not needed I think
|
||||||
|
lda NorthOpenEdge, x : sta $03 : inx
|
||||||
|
lda NorthEdgeInfo, x : sta $07 ;probably needed for maths - unsure
|
||||||
|
lda NorthOpenEdge, x : sta $04 : inx
|
||||||
|
lda NorthEdgeInfo, x : sta $08 ; needed for maths
|
||||||
|
lda NorthOpenEdge, x : sta $05
|
||||||
|
lda $04 : and #$0f : sta $00 : asl : !add $00 : tax
|
||||||
|
lda SouthEdgeInfo, x : sta $0a : inx ; needed now, and for nrml transition
|
||||||
|
lda SouthEdgeInfo, x : sta $0b : inx ; probably not needed - unsure
|
||||||
|
lda SouthEdgeInfo, x : sta $0c ; needed for maths
|
||||||
|
rts
|
||||||
|
|
||||||
|
LoadSouthData:
|
||||||
|
lda SouthEdgeInfo, x : sta $06
|
||||||
|
lda SouthOpenEdge, x : sta $03 : inx
|
||||||
|
lda SouthEdgeInfo, x : sta $07
|
||||||
|
lda SouthOpenEdge, x : sta $04 : inx
|
||||||
|
lda SouthEdgeInfo, x : sta $08
|
||||||
|
lda SouthOpenEdge, x : sta $05
|
||||||
|
lda $04 : and #$0f : sta $00 : asl : !add $00 : tax
|
||||||
|
lda NorthEdgeInfo, x : sta $0a : inx
|
||||||
|
lda NorthEdgeInfo, x : sta $0b : inx
|
||||||
|
lda NorthEdgeInfo, x : sta $0c
|
||||||
|
rts
|
||||||
|
|
||||||
|
LoadWestData:
|
||||||
|
lda WestEdgeInfo, x : sta $06
|
||||||
|
lda WestOpenEdge, x : sta $03 : inx
|
||||||
|
lda WestEdgeInfo, x : sta $07
|
||||||
|
lda WestOpenEdge, x : sta $04 : inx
|
||||||
|
lda WestEdgeInfo, x : sta $08
|
||||||
|
lda WestOpenEdge, x : sta $05
|
||||||
|
lda $04 : and #$0f : sta $00 : asl : !add $00 : tax
|
||||||
|
lda EastEdgeInfo, x : sta $0a : inx
|
||||||
|
lda EastEdgeInfo, x : sta $0b : inx
|
||||||
|
lda EastEdgeInfo, x : sta $0c
|
||||||
|
rts
|
||||||
|
|
||||||
|
LoadEastData:
|
||||||
|
lda EastEdgeInfo, x : sta $06
|
||||||
|
lda EastOpenEdge, x : sta $03 : inx
|
||||||
|
lda EastEdgeInfo, x : sta $07
|
||||||
|
lda EastOpenEdge, x : sta $04 : inx
|
||||||
|
lda EastEdgeInfo, x : sta $08
|
||||||
|
lda EastOpenEdge, x : sta $05
|
||||||
|
lda $04 : and #$0f : sta $00 : asl : !add $00 : tax
|
||||||
|
lda WestEdgeInfo, x : sta $0a : inx
|
||||||
|
lda WestEdgeInfo, x : sta $0b : inx
|
||||||
|
lda WestEdgeInfo, x : sta $0c
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
DetectNorthEdge:
|
||||||
|
ldx #$ff
|
||||||
|
lda $a2
|
||||||
|
cmp #$82 : bne +
|
||||||
|
lda $22 : cmp #$50 : bcs ++
|
||||||
|
ldx #$01 : bra .end
|
||||||
|
++ ldx #$00 : bra .end
|
||||||
|
+ cmp #$83 : bne +
|
||||||
|
ldx #$02 : bra .end
|
||||||
|
+ cmp #$84 : bne +
|
||||||
|
lda $a9 : beq ++
|
||||||
|
lda $22 : cmp #$78 : bcs +++
|
||||||
|
ldx #$04 : bra .end
|
||||||
|
+++ ldx #$05 : bra .end
|
||||||
|
++ lda $22 : cmp #$78 : bcs ++
|
||||||
|
ldx #$03 : bra .end
|
||||||
|
++ ldx #$04 : bra .end
|
||||||
|
+ cmp #$85 : bne +
|
||||||
|
ldx #$06 : bra .end
|
||||||
|
+ cmp #$db : bne +
|
||||||
|
lda $a9 : beq ++
|
||||||
|
lda $22 : beq ++
|
||||||
|
ldx #$08 : bra .end
|
||||||
|
++ ldx #$07 : bra .end
|
||||||
|
+ cmp #$dc : bne .end
|
||||||
|
lda $a9 : bne ++
|
||||||
|
lda $22 : cmp #$b0 : bcs ++
|
||||||
|
ldx #$09 : bra .end
|
||||||
|
++ ldx #$0a
|
||||||
|
.end txa : rts
|
||||||
|
|
||||||
|
DetectSouthEdge:
|
||||||
|
ldx #$ff
|
||||||
|
lda $a2
|
||||||
|
cmp #$72 : bne +
|
||||||
|
lda $22 : cmp #$50 : bcs ++
|
||||||
|
ldx #$01 : bra .end
|
||||||
|
++ ldx #$00 : bra .end
|
||||||
|
+ cmp #$73 : bne +
|
||||||
|
ldx #$02 : bra .end
|
||||||
|
+ cmp #$74 : bne +
|
||||||
|
lda $a9 : beq ++
|
||||||
|
lda $22 : cmp #$78 : bcs +++
|
||||||
|
ldx #$04 : bra .end
|
||||||
|
+++ ldx #$05 : bra .end
|
||||||
|
++ lda $22 : cmp #$78 : bcs ++
|
||||||
|
ldx #$03 : bra .end
|
||||||
|
++ ldx #$04 : bra .end
|
||||||
|
+ cmp #$75 : bne +
|
||||||
|
ldx #$06 : bra .end
|
||||||
|
+ cmp #$cb : bne +
|
||||||
|
lda $a9 : beq ++
|
||||||
|
lda $22 : beq ++
|
||||||
|
ldx #$08 : bra .end
|
||||||
|
++ ldx #$07 : bra .end
|
||||||
|
+ cmp #$cc : bne .end
|
||||||
|
lda $a9 : bne ++
|
||||||
|
lda $22 : cmp #$b0 : bcs ++
|
||||||
|
ldx #$09 : bra .end
|
||||||
|
++ ldx #$0a
|
||||||
|
.end txa : rts
|
||||||
|
|
||||||
|
DetectWestEdge:
|
||||||
|
ldx #$ff
|
||||||
|
lda $a2
|
||||||
|
cmp #$65 : bne +
|
||||||
|
ldx #$00 : bra .end
|
||||||
|
+ cmp #$74 : bne +
|
||||||
|
ldx #$01 : bra .end
|
||||||
|
+ cmp #$75 : bne +
|
||||||
|
ldx #$02 : bra .end
|
||||||
|
+ cmp #$82 : bne +
|
||||||
|
lda $aa : beq ++
|
||||||
|
ldx #$03 : bra .end
|
||||||
|
++ ldx #$04 : bra .end
|
||||||
|
+ cmp #$85 : bne +
|
||||||
|
ldx #$05 : bra .end
|
||||||
|
+ cmp #$cc : bne +
|
||||||
|
lda $aa : beq ++
|
||||||
|
ldx #$07 : bra .end
|
||||||
|
++ ldx #$06 : bra .end
|
||||||
|
+ cmp #$dc : bne .end
|
||||||
|
ldx #$08
|
||||||
|
.end txa : rts
|
||||||
|
|
||||||
|
DetectEastEdge:
|
||||||
|
ldx #$ff
|
||||||
|
lda $a2
|
||||||
|
cmp #$64 : bne +
|
||||||
|
ldx #$00 : bra .end
|
||||||
|
+ cmp #$73 : bne +
|
||||||
|
ldx #$01 : bra .end
|
||||||
|
+ cmp #$74 : bne +
|
||||||
|
ldx #$02 : bra .end
|
||||||
|
+ cmp #$81 : bne +
|
||||||
|
lda $aa : beq ++
|
||||||
|
ldx #$04 : bra .end
|
||||||
|
++ ldx #$03 : bra .end
|
||||||
|
+ cmp #$84 : bne +
|
||||||
|
ldx #$05 : bra .end
|
||||||
|
+ cmp #$cb : bne +
|
||||||
|
lda $aa : beq ++
|
||||||
|
ldx #$07 : bra .end
|
||||||
|
++ ldx #$06 : bra .end
|
||||||
|
+ cmp #$db : bne .end
|
||||||
|
ldx #$08
|
||||||
|
.end txa : rts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
61
asm/math.asm
Normal file
61
asm/math.asm
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
;divide by 2 example
|
||||||
|
; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10--Offset Ruler
|
||||||
|
;v 00 01 01 02 02 03 03 04 04 04 05 05 06 06 07 07 08
|
||||||
|
|
||||||
|
;divide by 3 example
|
||||||
|
; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18
|
||||||
|
;00 00 01 01 01 02 02 02 03 03 03 04 04 04 05 05 05 06 06 06 07 07 07 08 08
|
||||||
|
|
||||||
|
MultiplyByY:
|
||||||
|
.loop cpy #$0001 : beq .done
|
||||||
|
cpy #$0003 : bne ++
|
||||||
|
jsr MultiBy3 : bra .done
|
||||||
|
++ cpy #$0005 : bne ++
|
||||||
|
jsr MultiBy5 : bra .done
|
||||||
|
++ asl : sta $00 : tya : lsr : tay : lda $00 : bra .loop
|
||||||
|
.done rts
|
||||||
|
|
||||||
|
;todo -- width in X?
|
||||||
|
DivideByY:
|
||||||
|
.loop cpy #$0001 : beq .done
|
||||||
|
cpy #$0003 : bne ++
|
||||||
|
jsr DivideBy3 : bra .done
|
||||||
|
++ cpy #$0005 : bne ++
|
||||||
|
jsr DivideBy5 : bra .done
|
||||||
|
; todo -- alter - width
|
||||||
|
++ tyx : jsr DivideBy2 : sta $00 : tya : lsr : tay : lda $00 : bra .loop
|
||||||
|
.done rts
|
||||||
|
|
||||||
|
MultiBy3:
|
||||||
|
sta $00 : asl : !add $00
|
||||||
|
rts
|
||||||
|
|
||||||
|
MultiBy5:
|
||||||
|
sta $00 : asl #2 : !add $00
|
||||||
|
rts
|
||||||
|
|
||||||
|
;width of divison in x
|
||||||
|
DivideBy2:
|
||||||
|
sta $00
|
||||||
|
lsr : bcc .done
|
||||||
|
sta $02 : txa : lsr : cmp $00 : !bge .done
|
||||||
|
lda $02 : inc
|
||||||
|
.done rts
|
||||||
|
|
||||||
|
DivideBy3:
|
||||||
|
sta $00
|
||||||
|
ldx #$0000
|
||||||
|
lda #$0002
|
||||||
|
.loop cmp $00 : !bge .store
|
||||||
|
inx : !add #$0003 : bra .loop
|
||||||
|
.store txa
|
||||||
|
rts
|
||||||
|
|
||||||
|
DivideBy5:
|
||||||
|
sta $00
|
||||||
|
ldx #$0000
|
||||||
|
lda #$0003
|
||||||
|
.loop cmp $00 : !bge .store
|
||||||
|
inx : !add #$0005 : bra .loop
|
||||||
|
.store txa
|
||||||
|
rts
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
WarpLeft:
|
WarpLeft:
|
||||||
|
lda DRMode : beq .end
|
||||||
lda $040c : cmp.b #$ff : beq .end
|
lda $040c : cmp.b #$ff : beq .end
|
||||||
lda $20 : ldx $aa
|
lda $20 : ldx $aa
|
||||||
jsr CalcIndex
|
jsr CalcIndex
|
||||||
@@ -9,6 +10,7 @@ WarpLeft:
|
|||||||
rtl
|
rtl
|
||||||
|
|
||||||
WarpRight:
|
WarpRight:
|
||||||
|
lda DRMode : beq .end
|
||||||
lda $040c : cmp.b #$ff : beq .end
|
lda $040c : cmp.b #$ff : beq .end
|
||||||
lda $20 : ldx $aa
|
lda $20 : ldx $aa
|
||||||
jsr CalcIndex
|
jsr CalcIndex
|
||||||
@@ -19,6 +21,7 @@ WarpRight:
|
|||||||
rtl
|
rtl
|
||||||
|
|
||||||
WarpUp:
|
WarpUp:
|
||||||
|
lda DRMode : beq .end
|
||||||
lda $040c : cmp.b #$ff : beq .end
|
lda $040c : cmp.b #$ff : beq .end
|
||||||
lda $22 : ldx $a9
|
lda $22 : ldx $a9
|
||||||
jsr CalcIndex
|
jsr CalcIndex
|
||||||
@@ -29,6 +32,7 @@ WarpUp:
|
|||||||
rtl
|
rtl
|
||||||
|
|
||||||
WarpDown:
|
WarpDown:
|
||||||
|
lda DRMode : beq .end
|
||||||
lda $040c : cmp.b #$ff : beq .end
|
lda $040c : cmp.b #$ff : beq .end
|
||||||
lda $22 : ldx $a9
|
lda $22 : ldx $a9
|
||||||
jsr CalcIndex
|
jsr CalcIndex
|
||||||
@@ -39,11 +43,11 @@ WarpDown:
|
|||||||
rtl
|
rtl
|
||||||
|
|
||||||
TrapDoorFixer:
|
TrapDoorFixer:
|
||||||
lda $ab : and #$0038 : beq .end
|
lda $fe : and #$0038 : beq .end
|
||||||
xba : asl #2 : sta $00
|
xba : asl #2 : sta $00
|
||||||
stz $0468 : lda $068c : ora $00 : sta $068c
|
stz $0468 : lda $068c : ora $00 : sta $068c
|
||||||
.end
|
.end
|
||||||
stz $ab ; clear our ab here because we don't need it anymore
|
stz $fe ; clear our ab here because we don't need it anymore
|
||||||
rts
|
rts
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
@@ -72,7 +76,9 @@ LoadRoomHorz:
|
|||||||
sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack
|
sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack
|
||||||
lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00
|
lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00
|
||||||
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
|
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
|
||||||
pla : sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
|
; jsr HorzEdge : pla : bcs .end
|
||||||
|
pla
|
||||||
|
sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
|
||||||
|
|
||||||
.gtg ;Good to Go!
|
.gtg ;Good to Go!
|
||||||
pla ; Throw away normal room (don't fill up the stack)
|
pla ; Throw away normal room (don't fill up the stack)
|
||||||
@@ -84,7 +90,8 @@ LoadRoomHorz:
|
|||||||
jsr ShiftQuad
|
jsr ShiftQuad
|
||||||
jsr ShiftCameraBounds
|
jsr ShiftCameraBounds
|
||||||
ldy #$01 : jsr ShiftVariablesSubDir ; flip direction
|
ldy #$01 : jsr ShiftVariablesSubDir ; flip direction
|
||||||
lda $01 : sta $ab : and #$04 : lsr #2
|
jsr SetupScrollIndicator
|
||||||
|
lda $01 : sta $fe : and #$04 : lsr #2
|
||||||
sta $ee
|
sta $ee
|
||||||
lda $01 : and #$10 : beq .end : stz $0468
|
lda $01 : and #$10 : beq .end : stz $0468
|
||||||
.end
|
.end
|
||||||
@@ -100,8 +107,9 @@ LoadRoomVert:
|
|||||||
sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack
|
sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack
|
||||||
lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00
|
lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00
|
||||||
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
|
lda $01 : and.b #$80 : cmp #$80 : bne .gtg
|
||||||
pla : sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
|
; jsr VertEdge : pla : bcs .end
|
||||||
|
pla
|
||||||
|
sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine)
|
||||||
.gtg ;Good to Go!
|
.gtg ;Good to Go!
|
||||||
pla ; Throw away normal room (don't fill up the stack)
|
pla ; Throw away normal room (don't fill up the stack)
|
||||||
lda $a0 : and.b #$F0 : lsr #3 : !sub $21 : !add $06 : sta $02
|
lda $a0 : and.b #$F0 : lsr #3 : !sub $21 : !add $06 : sta $02
|
||||||
@@ -111,13 +119,20 @@ LoadRoomVert:
|
|||||||
jsr ShiftQuad
|
jsr ShiftQuad
|
||||||
jsr ShiftCameraBounds
|
jsr ShiftCameraBounds
|
||||||
ldy #$00 : jsr ShiftVariablesSubDir ; flip direction
|
ldy #$00 : jsr ShiftVariablesSubDir ; flip direction
|
||||||
lda $01 : sta $ab : and #$04 : lsr #2
|
jsr SetupScrollIndicator
|
||||||
|
lda $01 : sta $fe : and #$04 : lsr #2
|
||||||
sta $ee
|
sta $ee
|
||||||
.end
|
.end
|
||||||
plb ; restore db register
|
plb ; restore db register
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetupScrollIndicator:
|
||||||
|
lda $ab : and #$01 : asl : sta $ac
|
||||||
|
lda $ab : and #$40 : clc : rol #3 : ora $ac : sta $ac
|
||||||
|
lda $ab : and #$20 : asl #2 : sta $ab
|
||||||
|
rts
|
||||||
|
|
||||||
LookupNewRoom: ; expects data offset to be in A
|
LookupNewRoom: ; expects data offset to be in A
|
||||||
{
|
{
|
||||||
rep #$30 : and #$00FF ;sanitize A reg (who knows what is in the high byte)
|
rep #$30 : and #$00FF ;sanitize A reg (who knows what is in the high byte)
|
||||||
@@ -132,7 +147,7 @@ LookupNewRoom: ; expects data offset to be in A
|
|||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
; INPUTS-- X: Direction Index , $02: Shift Value
|
; INPUTS-- Y: Direction Index , $02: Shift Value
|
||||||
; Sets high bytes of various registers
|
; Sets high bytes of various registers
|
||||||
ShiftVariablesMainDir:
|
ShiftVariablesMainDir:
|
||||||
{
|
{
|
||||||
@@ -152,7 +167,7 @@ ShiftLowCoord:
|
|||||||
{
|
{
|
||||||
lda $01 : and.b #$03 ; high byte index
|
lda $01 : and.b #$03 ; high byte index
|
||||||
jsr CalcOpposingShift
|
jsr CalcOpposingShift
|
||||||
lda $fe : and.b #$f0 : cmp.b #$20 : bne .lowDone
|
lda $ab : and.b #$f0 : cmp.b #$20 : bne .lowDone
|
||||||
lda OppCoordIndex,y : tax
|
lda OppCoordIndex,y : tax
|
||||||
lda #$80 : !add $20,x : sta $20,x
|
lda #$80 : !add $20,x : sta $20,x
|
||||||
.lowDone
|
.lowDone
|
||||||
@@ -160,13 +175,13 @@ ShiftLowCoord:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; expects A to be (0,1,2) (dest number) and (0,1,2) (src door number) to be stored in $04
|
; expects A to be (0,1,2) (dest number) and (0,1,2) (src door number) to be stored in $04
|
||||||
; $0127 will be set to a bitmask aaaa qxxf
|
; $ab will be set to a bitmask aaaa qxxf
|
||||||
; a - amount of adjust
|
; a - amount of adjust
|
||||||
; f - flag, if set, then amount is pos, otherwise neg.
|
; f - flag, if set, then amount is pos, otherwise neg.
|
||||||
; q - quadrant, if set, then quadrant needs to be modified
|
; q - quadrant, if set, then quadrant needs to be modified
|
||||||
CalcOpposingShift:
|
CalcOpposingShift:
|
||||||
{
|
{
|
||||||
stz $fe ; set up (can you zero out 127 alone?)
|
stz $ab : stz $ac ; set up
|
||||||
cmp.b $04 : beq .noOffset ; (equal, no shifts to do)
|
cmp.b $04 : beq .noOffset ; (equal, no shifts to do)
|
||||||
phy : tay ; reserve these
|
phy : tay ; reserve these
|
||||||
lda $04 : tax : tya : !sub $04 : sta $04 : cmp.b #$00 : bpl .shiftPos
|
lda $04 : tax : tya : !sub $04 : sta $04 : cmp.b #$00 : bpl .shiftPos
|
||||||
@@ -174,8 +189,8 @@ CalcOpposingShift:
|
|||||||
cpx.b #$01 : beq .skipNegQuad
|
cpx.b #$01 : beq .skipNegQuad
|
||||||
ora #$08
|
ora #$08
|
||||||
.skipNegQuad
|
.skipNegQuad
|
||||||
sta $fe : lda $04 : cmp.b #$FE : beq .done ;already set $0127
|
sta $ab : lda $04 : cmp.b #$FE : beq .done ;already set $ab
|
||||||
lda $fe : eor #$60
|
lda $ab : eor #$60
|
||||||
bra .setDone
|
bra .setDone
|
||||||
|
|
||||||
.shiftPos
|
.shiftPos
|
||||||
@@ -183,10 +198,10 @@ CalcOpposingShift:
|
|||||||
cpy.b #$01 : beq .skipPosQuad
|
cpy.b #$01 : beq .skipPosQuad
|
||||||
ora #$08
|
ora #$08
|
||||||
.skipPosQuad
|
.skipPosQuad
|
||||||
sta $fe : lda $04 : cmp.b #$02 : bcs .done ;already set $0127
|
sta $ab : lda $04 : cmp.b #$02 : bcs .done ;already set $ab
|
||||||
lda $fe : eor #$60
|
lda $ab : eor #$60
|
||||||
|
|
||||||
.setDone sta $fe
|
.setDone sta $ab
|
||||||
.done ply
|
.done ply
|
||||||
.noOffset rts
|
.noOffset rts
|
||||||
}
|
}
|
||||||
@@ -194,9 +209,9 @@ CalcOpposingShift:
|
|||||||
|
|
||||||
ShiftQuad:
|
ShiftQuad:
|
||||||
{
|
{
|
||||||
lda $fe : and #$08 : cmp.b #$00 : beq .quadDone
|
lda $ab : and #$08 : beq .quadDone
|
||||||
lda ShiftQuadIndex,y : tax ; X should be set to either 1 (vertical) or 2 (horizontal) (for a9,aa quadrant)
|
lda ShiftQuadIndex,y : tax ; X should be set to either 1 (vertical) or 2 (horizontal) (for a9,aa quadrant)
|
||||||
lda $fe : and #$01 : cmp.b #$00 : beq .decQuad
|
lda $ab : and #$01 : beq .decQuad
|
||||||
inc $02
|
inc $02
|
||||||
txa : sta $a8, x ; alter a9/aa
|
txa : sta $a8, x ; alter a9/aa
|
||||||
bra .quadDone
|
bra .quadDone
|
||||||
@@ -224,8 +239,8 @@ ShiftCameraBounds:
|
|||||||
{
|
{
|
||||||
lda CamBoundIndex,y : tax ; should be 0 for horz travel (vert bounds) or 4 for vert travel (horz bounds)
|
lda CamBoundIndex,y : tax ; should be 0 for horz travel (vert bounds) or 4 for vert travel (horz bounds)
|
||||||
rep #$30
|
rep #$30
|
||||||
lda $fe : and #$00f0 : asl #2 : sta $06
|
lda $ab : and #$00f0 : asl #2 : sta $06
|
||||||
lda $fe : and #$0001 : cmp #$0000 : beq .subIt
|
lda $ab : and #$0001 : cmp #$0000 : beq .subIt
|
||||||
lda $0618, x : !add $06 : sta $0618, x
|
lda $0618, x : !add $06 : sta $0618, x
|
||||||
lda $061A, x : !add $06 : sta $061A, x
|
lda $061A, x : !add $06 : sta $061A, x
|
||||||
sep #$30
|
sep #$30
|
||||||
@@ -239,19 +254,26 @@ ShiftCameraBounds:
|
|||||||
|
|
||||||
AdjustTransition:
|
AdjustTransition:
|
||||||
{
|
{
|
||||||
lda $fe : and #$00f0 : lsr
|
lda $ab : and #$01ff : beq .reset
|
||||||
sep #$20 : cmp $0126 : bcc .reset
|
|
||||||
rep #$20
|
|
||||||
phy : ldy #$06 ; operating on vertical registers during horizontal trans
|
phy : ldy #$06 ; operating on vertical registers during horizontal trans
|
||||||
cpx.b #$02 : bcs .horizontalScrolling
|
cpx.b #$02 : bcs .horizontalScrolling
|
||||||
ldy #$00 ; operate on horizontal regs during vert trans
|
ldy #$00 ; operate on horizontal regs during vert trans
|
||||||
.horizontalScrolling
|
.horizontalScrolling
|
||||||
lda $fe : and #$0001 : asl : tax
|
cmp #$0008 : bcs +
|
||||||
lda.l OffsetTable,x : adc $00E2,y : and.w #$FFFE : sta $00E2,y : sta $00E0,y
|
pha : lda $ab : and #$0200 : beq ++
|
||||||
|
pla : bra .add
|
||||||
|
++ pla : eor #$ffff : inc ; convert to negative
|
||||||
|
.add jsr AdjustCamAdd : ply : bra .reset
|
||||||
|
+ lda $ab : and #$0200 : xba : tax
|
||||||
|
lda.l OffsetTable,x : jsr AdjustCamAdd
|
||||||
|
lda $ab : !sub #$0008 : sta $ab
|
||||||
ply : bra .done
|
ply : bra .done
|
||||||
.reset ; clear the 0127 variable so to not disturb intra-tile doors
|
.reset ; clear the $ab variable so to not disturb intra-tile doors
|
||||||
stz $fe
|
stz $ab
|
||||||
.done
|
.done
|
||||||
rep #$20 : lda $00 : and #$01fc
|
lda $00 : and #$01fc
|
||||||
rtl
|
rtl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AdjustCamAdd:
|
||||||
|
!add $00E2,y : sta $00E2,y : sta $00E0,y : rts
|
||||||
@@ -49,7 +49,7 @@ def custom_page(top, parent):
|
|||||||
for key in dictWidgets:
|
for key in dictWidgets:
|
||||||
self.customWidgets[key] = dictWidgets[key]
|
self.customWidgets[key] = dictWidgets[key]
|
||||||
|
|
||||||
for i, key in enumerate(CONST.CUSTOMITEMS):
|
for key in CONST.CUSTOMITEMS:
|
||||||
self.customWidgets[key].storageVar.set(top.settings["customitemarray"][i])
|
self.customWidgets[key].storageVar.set(top.settings["customitemarray"][key])
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -37,9 +37,10 @@
|
|||||||
"selectbox": {
|
"selectbox": {
|
||||||
"side": "right"
|
"side": "right"
|
||||||
},
|
},
|
||||||
"default": "Off"
|
"default": "Auto"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
"Auto": "default",
|
||||||
"Off": "off",
|
"Off": "off",
|
||||||
"On": "on",
|
"On": "on",
|
||||||
"On Compass Pickup": "pickup"
|
"On Compass Pickup": "pickup"
|
||||||
|
|||||||
Reference in New Issue
Block a user