Logic added for openable trap doors
This commit is contained in:
@@ -1760,6 +1760,7 @@ class Door(object):
|
|||||||
self.dest = None
|
self.dest = None
|
||||||
self.blocked = False # Indicates if the door is normally blocked off as an exit. (Sanc door or always closed)
|
self.blocked = False # Indicates if the door is normally blocked off as an exit. (Sanc door or always closed)
|
||||||
self.blocked_orig = False
|
self.blocked_orig = False
|
||||||
|
self.trapped = False
|
||||||
self.stonewall = False # Indicate that the door cannot be enter until exited (Desert Torches, PoD Eye Statue)
|
self.stonewall = False # Indicate that the door cannot be enter until exited (Desert Torches, PoD Eye Statue)
|
||||||
self.smallKey = False # There's a small key door on this side
|
self.smallKey = False # There's a small key door on this side
|
||||||
self.bigKey = False # There's a big key door on this side
|
self.bigKey = False # There's a big key door on this side
|
||||||
@@ -1870,7 +1871,7 @@ class Door(object):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def no_exit(self):
|
def no_exit(self):
|
||||||
self.blocked = self.blocked_orig = True
|
self.blocked = self.blocked_orig = self.trapped = True
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def no_entrance(self):
|
def no_entrance(self):
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ def link_doors_prep(world, player):
|
|||||||
|
|
||||||
find_inaccessible_regions(world, player)
|
find_inaccessible_regions(world, player)
|
||||||
|
|
||||||
if world.doorShuffle[player] != 'vanilla':
|
create_dungeon_pool(world, player)
|
||||||
create_dungeon_pool(world, player)
|
|
||||||
if world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla':
|
if world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla':
|
||||||
choose_portals(world, player)
|
choose_portals(world, player)
|
||||||
else:
|
else:
|
||||||
@@ -1844,12 +1843,12 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, wo
|
|||||||
builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, all_custom[dungeon])
|
builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, all_custom[dungeon])
|
||||||
remaining -= len(custom_trap_doors[dungeon])
|
remaining -= len(custom_trap_doors[dungeon])
|
||||||
ttl += len(builder.candidates.trap)
|
ttl += len(builder.candidates.trap)
|
||||||
if ttl == 0:
|
if ttl == 0 and all(len(custom_trap_doors[dungeon]) == 0 for dungeon in pool):
|
||||||
continue
|
continue
|
||||||
for dungeon in pool:
|
for dungeon in pool:
|
||||||
builder = world.dungeon_layouts[player][dungeon]
|
builder = world.dungeon_layouts[player][dungeon]
|
||||||
proportion = len(builder.candidates.trap)
|
proportion = len(builder.candidates.trap)
|
||||||
calc = int(round(proportion * door_type_pool.traps/ttl))
|
calc = 0 if ttl == 0 else int(round(proportion * door_type_pool.traps/ttl))
|
||||||
suggested = min(proportion, calc)
|
suggested = min(proportion, calc)
|
||||||
remaining -= suggested
|
remaining -= suggested
|
||||||
suggestion_map[dungeon] = suggested
|
suggestion_map[dungeon] = suggested
|
||||||
@@ -1981,7 +1980,10 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_
|
|||||||
remaining = max(0, remaining)
|
remaining = max(0, remaining)
|
||||||
for dungeon in pool:
|
for dungeon in pool:
|
||||||
builder = world.dungeon_layouts[player][dungeon]
|
builder = world.dungeon_layouts[player][dungeon]
|
||||||
calculated = int(round(builder.key_doors_num*total_keys/ttl))
|
if ttl == 0:
|
||||||
|
calculated = 0
|
||||||
|
else:
|
||||||
|
calculated = int(round(builder.key_doors_num*total_keys/ttl))
|
||||||
max_keys = max(0, builder.location_cnt - calc_used_dungeon_items(builder, world, player))
|
max_keys = max(0, builder.location_cnt - calc_used_dungeon_items(builder, world, player))
|
||||||
cand_len = max(0, len(builder.candidates.small) - builder.key_drop_cnt)
|
cand_len = max(0, len(builder.candidates.small) - builder.key_drop_cnt)
|
||||||
limit = min(max_keys, cand_len, max_computation)
|
limit = min(max_keys, cand_len, max_computation)
|
||||||
@@ -2211,9 +2213,10 @@ def find_valid_trap_combination(builder, suggested, start_regions, paths, world,
|
|||||||
sample_list = build_sample_list(combinations, 1000)
|
sample_list = build_sample_list(combinations, 1000)
|
||||||
proposal = kth_combination(sample_list[itr], trap_door_pool, trap_doors_needed)
|
proposal = kth_combination(sample_list[itr], trap_door_pool, trap_doors_needed)
|
||||||
proposal.extend(custom_trap_doors)
|
proposal.extend(custom_trap_doors)
|
||||||
|
filtered_proposal = [x for x in proposal if x.name not in trap_door_exceptions]
|
||||||
|
|
||||||
start_regions, event_starts = filter_start_regions(builder, start_regions, world, player)
|
start_regions, event_starts = filter_start_regions(builder, start_regions, world, player)
|
||||||
while not validate_trap_layout(proposal, builder, start_regions, paths, world, player):
|
while not validate_trap_layout(filtered_proposal, builder, start_regions, paths, world, player):
|
||||||
itr += 1
|
itr += 1
|
||||||
if itr >= len(sample_list):
|
if itr >= len(sample_list):
|
||||||
if not drop:
|
if not drop:
|
||||||
@@ -2248,6 +2251,12 @@ def filter_start_regions(builder, start_regions, world, player):
|
|||||||
portal_entrance_region = portal.door.entrance.parent_region.name
|
portal_entrance_region = portal.door.entrance.parent_region.name
|
||||||
if portal_entrance_region not in builder.path_entrances:
|
if portal_entrance_region not in builder.path_entrances:
|
||||||
excluded[region] = None
|
excluded[region] = None
|
||||||
|
if not portal:
|
||||||
|
drop_region = next((x.parent_region for x in region.entrances
|
||||||
|
if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld]
|
||||||
|
or x.parent_region.name == 'Sewer Drop'), None)
|
||||||
|
if drop_region and drop_region.name in world.inaccessible_regions[player]:
|
||||||
|
excluded[region] = None
|
||||||
if std_flag and (not portal or portal.find_portal_entrance().parent_region.name != 'Hyrule Castle Courtyard'):
|
if std_flag and (not portal or portal.find_portal_entrance().parent_region.name != 'Hyrule Castle Courtyard'):
|
||||||
excluded[region] = None
|
excluded[region] = None
|
||||||
if portal is None:
|
if portal is None:
|
||||||
@@ -2343,10 +2352,12 @@ def reassign_trap_doors(trap_map, world, player):
|
|||||||
elif kind in [DoorKind.Trap2, DoorKind.TrapTriggerable]:
|
elif kind in [DoorKind.Trap2, DoorKind.TrapTriggerable]:
|
||||||
room.change(d.doorListPos, DoorKind.Normal)
|
room.change(d.doorListPos, DoorKind.Normal)
|
||||||
d.blocked = False
|
d.blocked = False
|
||||||
|
d.trapped = False
|
||||||
# connect_one_way(world, d.name, d.dest.name, player)
|
# connect_one_way(world, d.name, d.dest.name, player)
|
||||||
elif d.type is DoorType.Normal and d not in traps:
|
elif d.type is DoorType.Normal and d not in traps:
|
||||||
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
|
||||||
d.blocked = False
|
d.blocked = False
|
||||||
|
d.trapped = False
|
||||||
for d in traps:
|
for d in traps:
|
||||||
change_door_to_trap(d, world, player)
|
change_door_to_trap(d, world, player)
|
||||||
world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Trap Door', player)
|
world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Trap Door', player)
|
||||||
@@ -2384,24 +2395,45 @@ def change_door_to_trap(d, world, player):
|
|||||||
elif d.direction in [Direction.North, Direction.West]:
|
elif d.direction in [Direction.North, Direction.West]:
|
||||||
new_kind = DoorKind.TrapTriggerable
|
new_kind = DoorKind.TrapTriggerable
|
||||||
if new_kind:
|
if new_kind:
|
||||||
d.blocked = True
|
d.blocked = is_trap_door_blocked(d)
|
||||||
|
d.trapped = True
|
||||||
pos = 3 if d.type == DoorType.Normal else 4
|
pos = 3 if d.type == DoorType.Normal else 4
|
||||||
verify_door_list_pos(d, room, world, player, pos)
|
verify_door_list_pos(d, room, world, player, pos)
|
||||||
d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1, 3: 0x8}[d.doorListPos]
|
d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1, 3: 0x8}[d.doorListPos]
|
||||||
room.change(d.doorListPos, new_kind)
|
room.change(d.doorListPos, new_kind)
|
||||||
if d.entrance.connected_region is not None:
|
if d.entrance.connected_region is not None and d.blocked:
|
||||||
d.entrance.connected_region.entrances.remove(d.entrance)
|
d.entrance.connected_region.entrances.remove(d.entrance)
|
||||||
d.entrance.connected_region = None
|
d.entrance.connected_region = None
|
||||||
elif d.type is DoorType.Normal:
|
elif d.type is DoorType.Normal:
|
||||||
d.blocked = True
|
d.blocked = is_trap_door_blocked(d)
|
||||||
|
d.trapped = True
|
||||||
verify_door_list_pos(d, room, world, player, pos=3)
|
verify_door_list_pos(d, room, world, player, pos=3)
|
||||||
d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos]
|
d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos]
|
||||||
room.change(d.doorListPos, DoorKind.Trap)
|
room.change(d.doorListPos, DoorKind.Trap)
|
||||||
if d.entrance.connected_region is not None:
|
if d.entrance.connected_region is not None and d.blocked:
|
||||||
d.entrance.connected_region.entrances.remove(d.entrance)
|
d.entrance.connected_region.entrances.remove(d.entrance)
|
||||||
d.entrance.connected_region = None
|
d.entrance.connected_region = None
|
||||||
|
|
||||||
|
|
||||||
|
trap_door_exceptions = {
|
||||||
|
'PoD Mimics 2 SW', 'TR Twin Pokeys NW', 'Thieves Blocked Entry SW', 'Hyrule Dungeon Armory Interior Key Door N',
|
||||||
|
'Desert Compass Key Door WN', 'TR Tile Room SE', 'Mire Cross SW', 'Tower Circle of Pots ES',
|
||||||
|
'Eastern Single Eyegore ES', 'Eastern Duo Eyegores SE', 'Swamp Push Statue S',
|
||||||
|
'Skull 2 East Lobby WS', 'GT Hope Room WN', 'Eastern Courtyard Ledge S', 'Ice Lobby SE', 'GT Speed Torch WN',
|
||||||
|
'Ice Switch Room ES', 'Ice Switch Room NE', 'Skull Torch Room WS', 'GT Speed Torch NE', 'GT Speed Torch WS',
|
||||||
|
'GT Torch Cross WN', 'Mire Tile Room SW', 'Mire Tile Room ES', 'TR Torches WN', 'PoD Lobby N', 'PoD Middle Cage S',
|
||||||
|
'Ice Bomb Jump NW', 'GT Hidden Spikes SE', 'Ice Tall Hint EN', 'GT Conveyor Cross EN', 'Eastern Pot Switch WN',
|
||||||
|
'Thieves Conveyor Maze WN', 'Thieves Conveyor Maze SW', 'Eastern Dark Square Key Door WN', 'Eastern Lobby NW',
|
||||||
|
'Eastern Lobby NE', 'Ice Cross Bottom SE', 'Desert Back Lobby S', 'Desert West S',
|
||||||
|
'Desert West Lobby ES', 'Mire Hidden Shooters SE', 'Mire Hidden Shooters ES', 'Mire Hidden Shooters WS',
|
||||||
|
'Tower Dark Pits EN', 'Tower Dark Maze ES', 'TR Tongue Pull WS',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def is_trap_door_blocked(door):
|
||||||
|
return door.name not in trap_door_exceptions
|
||||||
|
|
||||||
|
|
||||||
def find_big_key_candidates(builder, start_regions, used, world, player):
|
def find_big_key_candidates(builder, start_regions, used, world, player):
|
||||||
if world.door_type_mode[player] != 'original': # big, all, chaos
|
if world.door_type_mode[player] != 'original': # big, all, chaos
|
||||||
# traverse dungeon and find candidates
|
# traverse dungeon and find candidates
|
||||||
|
|||||||
2
Main.py
2
Main.py
@@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
|
|||||||
from source.tools.BPS import create_bps_from_data
|
from source.tools.BPS import create_bps_from_data
|
||||||
from source.classes.CustomSettings import CustomSettings
|
from source.classes.CustomSettings import CustomSettings
|
||||||
|
|
||||||
version_number = '1.2.0.19'
|
version_number = '1.2.0.20'
|
||||||
version_branch = '-u'
|
version_branch = '-u'
|
||||||
__version__ = f'{version_number}{version_branch}'
|
__version__ = f'{version_number}{version_branch}'
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,9 @@ These are now independent of retro mode and have three options: None, Random, an
|
|||||||
|
|
||||||
# Bug Fixes and Notes
|
# Bug Fixes and Notes
|
||||||
|
|
||||||
|
* 1.2.0.20u
|
||||||
|
* Added logic for trap doors that could be opened using existing room triggers
|
||||||
|
* Added a notes field for user added notes either via CLI or Customizer
|
||||||
* 1.2.0.19u
|
* 1.2.0.19u
|
||||||
* Added min/max for triforce pool, goal, and difference for CLI and Customizer. (Thanks Catobat)
|
* Added min/max for triforce pool, goal, and difference for CLI and Customizer. (Thanks Catobat)
|
||||||
* Fixed a bug with dungeon generation
|
* Fixed a bug with dungeon generation
|
||||||
|
|||||||
101
Rules.py
101
Rules.py
@@ -276,11 +276,18 @@ def global_rules(world, player):
|
|||||||
# Start of door rando rules
|
# Start of door rando rules
|
||||||
# TODO: Do these need to flag off when door rando is off? - some of them, yes
|
# TODO: Do these need to flag off when door rando is off? - some of them, yes
|
||||||
|
|
||||||
|
def is_trapped(entrance):
|
||||||
|
return world.get_entrance(entrance, player).door.trapped
|
||||||
|
|
||||||
# Eastern Palace
|
# Eastern Palace
|
||||||
# Eyegore room needs a bow
|
# Eyegore room needs a bow
|
||||||
set_rule(world.get_entrance('Eastern Duo Eyegores NE', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('Eastern Duo Eyegores NE', player), lambda state: state.can_shoot_arrows(player))
|
||||||
set_rule(world.get_entrance('Eastern Single Eyegore NE', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('Eastern Single Eyegore NE', player), lambda state: state.can_shoot_arrows(player))
|
||||||
set_rule(world.get_entrance('Eastern Map Balcony Hook Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('Eastern Map Balcony Hook Path', player), lambda state: state.has('Hookshot', player))
|
||||||
|
if is_trapped('Eastern Single Eyegore ES'):
|
||||||
|
set_rule(world.get_entrance('Eastern Single Eyegore ES', player), lambda state: state.can_shoot_arrows(player))
|
||||||
|
if is_trapped('Eastern Duo Eyegores SE'):
|
||||||
|
set_rule(world.get_entrance('Eastern Duo Eyegores SE', player), lambda state: state.can_shoot_arrows(player))
|
||||||
|
|
||||||
# Boss rules. Same as below but no BK or arrow requirement.
|
# Boss rules. Same as below but no BK or arrow requirement.
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Eastern Palace - Prize', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Eastern Palace - Prize', player))
|
||||||
@@ -305,13 +312,18 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Tower Red Spears WN', player), lambda state: state.can_kill_most_things(player))
|
set_rule(world.get_entrance('Tower Red Spears WN', player), lambda state: state.can_kill_most_things(player))
|
||||||
set_rule(world.get_entrance('Tower Red Guards EN', player), lambda state: state.can_kill_most_things(player))
|
set_rule(world.get_entrance('Tower Red Guards EN', player), lambda state: state.can_kill_most_things(player))
|
||||||
set_rule(world.get_entrance('Tower Red Guards SW', player), lambda state: state.can_kill_most_things(player))
|
set_rule(world.get_entrance('Tower Red Guards SW', player), lambda state: state.can_kill_most_things(player))
|
||||||
|
set_rule(world.get_entrance('Tower Circle of Pots NW', player), lambda state: state.can_kill_most_things(player))
|
||||||
|
if is_trapped('Tower Circle of Pots ES'):
|
||||||
|
set_rule(world.get_entrance('Tower Circle of Pots ES', player),
|
||||||
|
lambda state: state.can_kill_most_things(player))
|
||||||
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: state.has_sword(player))
|
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: state.has_sword(player))
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 1', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 1', player))
|
||||||
|
|
||||||
|
|
||||||
set_rule(world.get_entrance('PoD Arena Landing Bonk Path', player), lambda state: state.has_Boots(player))
|
set_rule(world.get_entrance('PoD Arena Landing Bonk Path', player), lambda state: state.has_Boots(player))
|
||||||
set_rule(world.get_entrance('PoD Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('PoD Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||||
set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||||
|
if is_trapped('PoD Mimics 2 SW'):
|
||||||
|
set_rule(world.get_entrance('PoD Mimics 2 SW', player), lambda state: state.can_shoot_arrows(player))
|
||||||
set_rule(world.get_entrance('PoD Bow Statue Down Ladder', player), lambda state: state.can_shoot_arrows(player))
|
set_rule(world.get_entrance('PoD Bow Statue Down Ladder', player), lambda state: state.can_shoot_arrows(player))
|
||||||
set_rule(world.get_entrance('PoD Map Balcony Drop Down', player), lambda state: state.has('Hammer', player))
|
set_rule(world.get_entrance('PoD Map Balcony Drop Down', player), lambda state: state.has('Hammer', player))
|
||||||
set_rule(world.get_entrance('PoD Dark Pegs Landing to Right', player), lambda state: state.has('Hammer', player))
|
set_rule(world.get_entrance('PoD Dark Pegs Landing to Right', player), lambda state: state.has('Hammer', player))
|
||||||
@@ -360,6 +372,8 @@ def global_rules(world, player):
|
|||||||
|
|
||||||
set_rule(world.get_entrance('Skull Big Chest Hookpath', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('Skull Big Chest Hookpath', player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Skull Torch Room WN', player), lambda state: state.has('Fire Rod', player))
|
set_rule(world.get_entrance('Skull Torch Room WN', player), lambda state: state.has('Fire Rod', player))
|
||||||
|
if is_trapped('Skull Torch Room WS'):
|
||||||
|
set_rule(world.get_entrance('Skull Torch Room WS', player), lambda state: state.has('Fire Rod', player))
|
||||||
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: state.has_sword(player))
|
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: state.has_sword(player))
|
||||||
|
|
||||||
hidden_pits_door = world.get_door('Skull Small Hall WS', player)
|
hidden_pits_door = world.get_door('Skull Small Hall WS', player)
|
||||||
@@ -397,6 +411,8 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_location('Thieves\' Town - Prize', player), lambda state: state.has('Maiden Unmasked', player) and world.get_location('Thieves\' Town - Prize', player).parent_region.dungeon.boss.can_defeat(state))
|
set_rule(world.get_location('Thieves\' Town - Prize', player), lambda state: state.has('Maiden Unmasked', player) and world.get_location('Thieves\' Town - Prize', player).parent_region.dungeon.boss.can_defeat(state))
|
||||||
|
|
||||||
set_rule(world.get_entrance('Ice Lobby WS', player), lambda state: state.can_melt_things(player))
|
set_rule(world.get_entrance('Ice Lobby WS', player), lambda state: state.can_melt_things(player))
|
||||||
|
if is_trapped('Ice Lobby SE'):
|
||||||
|
set_rule(world.get_entrance('Ice Lobby SE', player), lambda state: state.can_melt_things(player))
|
||||||
set_rule(world.get_entrance('Ice Hammer Block ES', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
set_rule(world.get_entrance('Ice Hammer Block ES', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||||
set_rule(world.get_location('Ice Palace - Hammer Block Key Drop', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
set_rule(world.get_location('Ice Palace - Hammer Block Key Drop', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||||
set_rule(world.get_location('Ice Palace - Map Chest', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
set_rule(world.get_location('Ice Palace - Map Chest', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||||
@@ -411,6 +427,12 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Ice Hookshot Balcony Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('Ice Hookshot Balcony Path', player), lambda state: state.has('Hookshot', player))
|
||||||
if not world.get_door('Ice Switch Room SE', player).entranceFlag:
|
if not world.get_door('Ice Switch Room SE', player).entranceFlag:
|
||||||
set_rule(world.get_entrance('Ice Switch Room SE', player), lambda state: state.has('Cane of Somaria', player) or state.has('Convenient Block', player))
|
set_rule(world.get_entrance('Ice Switch Room SE', player), lambda state: state.has('Cane of Somaria', player) or state.has('Convenient Block', player))
|
||||||
|
if is_trapped('Ice Switch Room ES'):
|
||||||
|
set_rule(world.get_entrance('Ice Switch Room ES', player),
|
||||||
|
lambda state: state.has('Cane of Somaria', player) or state.has('Convenient Block', player))
|
||||||
|
if is_trapped('Ice Switch Room NE'):
|
||||||
|
set_rule(world.get_entrance('Ice Switch Room NE', player),
|
||||||
|
lambda state: state.has('Cane of Somaria', player) or state.has('Convenient Block', player))
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Ice Palace - Boss', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Ice Palace - Boss', player))
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Ice Palace - Prize', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Ice Palace - Prize', player))
|
||||||
|
|
||||||
@@ -431,8 +453,15 @@ def global_rules(world, player):
|
|||||||
or state.has('Cane of Byrna', player) or state.has('Cape', player))
|
or state.has('Cane of Byrna', player) or state.has('Cape', player))
|
||||||
set_rule(world.get_entrance('Mire Left Bridge Hook Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('Mire Left Bridge Hook Path', player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Mire Tile Room NW', player), lambda state: state.has_fire_source(player))
|
set_rule(world.get_entrance('Mire Tile Room NW', player), lambda state: state.has_fire_source(player))
|
||||||
|
if is_trapped('Mire Tile Room SW'):
|
||||||
|
set_rule(world.get_entrance('Mire Tile Room SW', player), lambda state: state.has_fire_source(player))
|
||||||
|
if is_trapped('Mire Tile Room ES'):
|
||||||
|
set_rule(world.get_entrance('Mire Tile Room ES', player), lambda state: state.has_fire_source(player))
|
||||||
set_rule(world.get_entrance('Mire Attic Hint Hole', player), lambda state: state.has_fire_source(player))
|
set_rule(world.get_entrance('Mire Attic Hint Hole', player), lambda state: state.has_fire_source(player))
|
||||||
set_rule(world.get_entrance('Mire Dark Shooters SW', player), lambda state: state.has('Cane of Somaria', player))
|
set_rule(world.get_entrance('Mire Dark Shooters SW', player), lambda state: state.has('Cane of Somaria', player))
|
||||||
|
if is_trapped('Mire Dark Shooters SE'):
|
||||||
|
set_rule(world.get_entrance('Mire Dark Shooters SE', player),
|
||||||
|
lambda state: state.has('Cane of Somaria', player))
|
||||||
|
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Misery Mire - Boss', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Misery Mire - Boss', player))
|
||||||
set_defeat_dungeon_boss_rule(world.get_location('Misery Mire - Prize', player))
|
set_defeat_dungeon_boss_rule(world.get_location('Misery Mire - Prize', player))
|
||||||
@@ -448,6 +477,9 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('TR Hub Path', player), lambda state: state.has('Cane of Somaria', player))
|
set_rule(world.get_entrance('TR Hub Path', player), lambda state: state.has('Cane of Somaria', player))
|
||||||
set_rule(world.get_entrance('TR Hub Ledges Path', player), lambda state: state.has('Cane of Somaria', player))
|
set_rule(world.get_entrance('TR Hub Ledges Path', player), lambda state: state.has('Cane of Somaria', player))
|
||||||
set_rule(world.get_entrance('TR Torches NW', player), lambda state: state.has('Cane of Somaria', player) and state.has('Fire Rod', player))
|
set_rule(world.get_entrance('TR Torches NW', player), lambda state: state.has('Cane of Somaria', player) and state.has('Fire Rod', player))
|
||||||
|
if is_trapped('TR Torches WN'):
|
||||||
|
set_rule(world.get_entrance('TR Torches WN', player),
|
||||||
|
lambda state: state.has('Cane of Somaria', player) and state.has('Fire Rod', player))
|
||||||
set_rule(world.get_entrance('TR Big Chest Entrance Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has('Hookshot', player))
|
set_rule(world.get_entrance('TR Big Chest Entrance Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('TR Big Chest Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has_Boots(player))
|
set_rule(world.get_entrance('TR Big Chest Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has_Boots(player))
|
||||||
set_rule(world.get_entrance('TR Dark Ride Up Stairs', player), lambda state: state.has('Cane of Somaria', player))
|
set_rule(world.get_entrance('TR Dark Ride Up Stairs', player), lambda state: state.has('Cane of Somaria', player))
|
||||||
@@ -467,10 +499,20 @@ def global_rules(world, player):
|
|||||||
|
|
||||||
set_rule(world.get_location('Ganons Tower - Bob\'s Torch', player), lambda state: state.has_Boots(player))
|
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 Hope Room EN', player), lambda state: state.has('Cane of Somaria', player))
|
||||||
|
if is_trapped('GT Hope Room WN'):
|
||||||
|
set_rule(world.get_entrance('GT Hope Room WN', player), lambda state: state.has('Cane of Somaria', player))
|
||||||
set_rule(world.get_entrance('GT Conveyor Cross Hammer Path', player), lambda state: state.has('Hammer', player))
|
set_rule(world.get_entrance('GT Conveyor Cross Hammer Path', player), lambda state: state.has('Hammer', player))
|
||||||
set_rule(world.get_entrance('GT Conveyor Cross Hookshot Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('GT Conveyor Cross Hookshot Path', player), lambda state: state.has('Hookshot', player))
|
||||||
|
if is_trapped('GT Conveyor Cross EN'):
|
||||||
|
set_rule(world.get_entrance('GT Conveyor Cross EN', player), lambda state: state.has('Hammer', player))
|
||||||
if not world.get_door('GT Speed Torch SE', player).entranceFlag:
|
if not world.get_door('GT Speed Torch SE', player).entranceFlag:
|
||||||
set_rule(world.get_entrance('GT Speed Torch SE', player), lambda state: state.has('Fire Rod', player))
|
set_rule(world.get_entrance('GT Speed Torch SE', player), lambda state: state.has('Fire Rod', player))
|
||||||
|
if is_trapped('GT Speed Torch NE'):
|
||||||
|
set_rule(world.get_entrance('GT Speed Torch NE', player), lambda state: state.has('Fire Rod', player))
|
||||||
|
if is_trapped('GT Speed Torch WS'):
|
||||||
|
set_rule(world.get_entrance('GT Speed Torch WS', player), lambda state: state.has('Fire Rod', player))
|
||||||
|
if is_trapped('GT Speed Torch WN'):
|
||||||
|
set_rule(world.get_entrance('GT Speed Torch WN', player), lambda state: state.has('Fire Rod', player))
|
||||||
set_rule(world.get_entrance('GT Hookshot South-Mid Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('GT Hookshot South-Mid Path', player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('GT Hookshot Mid-North Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('GT Hookshot Mid-North Path', player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('GT Hookshot East-Mid Path', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
|
set_rule(world.get_entrance('GT Hookshot East-Mid Path', player), lambda state: state.has('Hookshot', player) or state.has_Boots(player))
|
||||||
@@ -505,6 +547,8 @@ def global_rules(world, player):
|
|||||||
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 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 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 Torch Cross ES', player), lambda state: state.has_fire_source(player))
|
||||||
|
if is_trapped('GT Torch Cross WN'):
|
||||||
|
set_rule(world.get_entrance('GT Torch Cross WN', 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 Falling Torches NE', player), lambda state: state.has_fire_source(player))
|
||||||
# todo: the following only applies to crystal state propagation from this supertile
|
# todo: the following only applies to crystal state propagation from this supertile
|
||||||
# you can also reset the supertile, but I'm not sure how to model that
|
# you can also reset the supertile, but I'm not sure how to model that
|
||||||
@@ -760,13 +804,29 @@ def bomb_rules(world, player):
|
|||||||
('GT Petting Zoo SE', False), # Dont make anyone do this room with bombs and/or pots.
|
('GT Petting Zoo SE', False), # Dont make anyone do this room with bombs and/or pots.
|
||||||
('GT DMs Room SW', False) # Four red stalfos
|
('GT DMs Room SW', False) # Four red stalfos
|
||||||
]
|
]
|
||||||
|
conditional_kill_traps = [
|
||||||
|
('Hyrule Dungeon Armory Interior Key Door N', True),
|
||||||
|
('Desert Compass Key Door WN', True),
|
||||||
|
('Thieves Blocked Entry SW', True),
|
||||||
|
('TR Tongue Pull WS', True),
|
||||||
|
('TR Twin Pokeys NW', False),
|
||||||
|
]
|
||||||
for killdoor,bombable in easy_kill_rooms:
|
for killdoor,bombable in easy_kill_rooms:
|
||||||
if bombable:
|
if bombable:
|
||||||
add_rule(world.get_entrance(killdoor, player), lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
add_rule(world.get_entrance(killdoor, player), lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
||||||
else:
|
else:
|
||||||
add_rule(world.get_entrance(killdoor, player), lambda state: state.can_kill_most_things(player))
|
add_rule(world.get_entrance(killdoor, player), lambda state: state.can_kill_most_things(player))
|
||||||
|
for kill_door, bombable in conditional_kill_traps:
|
||||||
|
if world.get_entrance(kill_door, player).door.trapped:
|
||||||
|
if bombable:
|
||||||
|
add_rule(world.get_entrance(kill_door, player),
|
||||||
|
lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
||||||
|
else:
|
||||||
|
add_rule(world.get_entrance(kill_door, player), lambda state: state.can_kill_most_things(player))
|
||||||
add_rule(world.get_entrance('Ice Stalfos Hint SE', player), lambda state: state.can_use_bombs(player)) # Need bombs for big stalfos knights
|
add_rule(world.get_entrance('Ice Stalfos Hint SE', player), lambda state: state.can_use_bombs(player)) # Need bombs for big stalfos knights
|
||||||
add_rule(world.get_entrance('Mire Cross ES', player), lambda state: state.can_kill_most_things(player)) # 4 Sluggulas. Bombs don't work // or (state.can_use_bombs(player) and state.has('Magic Powder'), player)
|
add_rule(world.get_entrance('Mire Cross ES', player), lambda state: state.can_kill_most_things(player)) # 4 Sluggulas. Bombs don't work // or (state.can_use_bombs(player) and state.has('Magic Powder'), player)
|
||||||
|
if world.get_entrance('Mire Cross SW', player).door.trapped:
|
||||||
|
add_rule(world.get_entrance('Mire Cross SW', player), lambda state: state.can_kill_most_things(player))
|
||||||
|
|
||||||
enemy_kill_drops = [ # Location, bool-bombable
|
enemy_kill_drops = [ # Location, bool-bombable
|
||||||
('Hyrule Castle - Map Guard Key Drop', True),
|
('Hyrule Castle - Map Guard Key Drop', True),
|
||||||
@@ -1143,6 +1203,9 @@ def swordless_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: True)
|
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: True)
|
||||||
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: True)
|
set_rule(world.get_entrance('Skull Vines NW', player), lambda state: True)
|
||||||
set_rule(world.get_entrance('Ice Lobby WS', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
set_rule(world.get_entrance('Ice Lobby WS', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
||||||
|
if world.get_entrance('Ice Lobby SE', player).door.trapped:
|
||||||
|
set_rule(world.get_entrance('Ice Lobby SE', player),
|
||||||
|
lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
||||||
set_rule(world.get_location('Ice Palace - Freezor Chest', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
set_rule(world.get_location('Ice Palace - Freezor Chest', player), lambda state: state.has('Fire Rod', player) or state.has('Bombos', player))
|
||||||
|
|
||||||
set_rule(world.get_location('Ether Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
|
set_rule(world.get_location('Ether Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
|
||||||
@@ -1156,7 +1219,7 @@ def swordless_rules(world, player):
|
|||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player))
|
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player))
|
||||||
|
|
||||||
|
# todo: new traps
|
||||||
std_kill_rooms = {
|
std_kill_rooms = {
|
||||||
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
||||||
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
||||||
@@ -1187,6 +1250,18 @@ std_kill_rooms = {
|
|||||||
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
||||||
} # all trap rooms?
|
} # all trap rooms?
|
||||||
|
|
||||||
|
std_kill_doors_if_trapped = {
|
||||||
|
'Hyrule Dungeon Armory Main': 'Hyrule Dungeon Armory Interior Key Door N',
|
||||||
|
# 'Eastern Single Eyegore ES', # arrow rule is sufficient
|
||||||
|
# 'Eastern Duo Eyegores S', # arrow rule is sufficient
|
||||||
|
'TR Twin Pokeys': 'TR Twin Pokeys NW',
|
||||||
|
'Thieves Basement Block': 'Thieves Blocked Entry SW',
|
||||||
|
'Desert Compass Room': 'Desert Compass Key Door WN',
|
||||||
|
'Mire Cross': 'Mire Cross SW',
|
||||||
|
'Tower Circle of Pots': 'Tower Circle of Pots ES',
|
||||||
|
# 'Ice Lobby S' # can melt rule is sufficient
|
||||||
|
}
|
||||||
|
|
||||||
def add_connection(parent_name, target_name, entrance_name, world, player):
|
def add_connection(parent_name, target_name, entrance_name, world, player):
|
||||||
parent = world.get_region(parent_name, player)
|
parent = world.get_region(parent_name, player)
|
||||||
target = world.get_region(target_name, player)
|
target = world.get_region(target_name, player)
|
||||||
@@ -1241,6 +1316,10 @@ def standard_rules(world, player):
|
|||||||
if region.name in std_kill_rooms:
|
if region.name in std_kill_rooms:
|
||||||
for ent in std_kill_rooms[region.name]:
|
for ent in std_kill_rooms[region.name]:
|
||||||
add_rule(world.get_entrance(ent, player), lambda state: standard_escape_rule(state))
|
add_rule(world.get_entrance(ent, player), lambda state: standard_escape_rule(state))
|
||||||
|
if region.name in std_kill_doors_if_trapped:
|
||||||
|
ent = world.get_entrance(std_kill_doors_if_trapped[region.name], player)
|
||||||
|
if ent.door.trapped:
|
||||||
|
add_rule(ent, lambda state: standard_escape_rule(state))
|
||||||
|
|
||||||
set_rule(world.get_location('Zelda Pickup', player), lambda state: state.has('Big Key (Escape)', player))
|
set_rule(world.get_location('Zelda Pickup', player), lambda state: state.has('Big Key (Escape)', player))
|
||||||
set_rule(world.get_entrance('Hyrule Castle Throne Room Tapestry', player), lambda state: state.has('Zelda Herself', player))
|
set_rule(world.get_entrance('Hyrule Castle Throne Room Tapestry', player), lambda state: state.has('Zelda Herself', player))
|
||||||
@@ -1866,6 +1945,11 @@ def set_bunny_rules(world, player, inverted):
|
|||||||
if is_bunny(bunny_exit.parent_region):
|
if is_bunny(bunny_exit.parent_region):
|
||||||
add_rule(bunny_exit, get_rule_to_add(bunny_exit.parent_region))
|
add_rule(bunny_exit, get_rule_to_add(bunny_exit.parent_region))
|
||||||
|
|
||||||
|
for ent_name in bunny_impassible_if_trapped:
|
||||||
|
bunny_exit = world.get_entrance(ent_name, player)
|
||||||
|
if bunny_exit.door.trapped and is_bunny(bunny_exit.parent_region):
|
||||||
|
add_rule(bunny_exit, get_rule_to_add(bunny_exit.parent_region))
|
||||||
|
|
||||||
doors_to_check = [x for x in world.doors if x.player == player and x not in bunny_impassible_doors]
|
doors_to_check = [x for x in world.doors if x.player == player and x not in bunny_impassible_doors]
|
||||||
doors_to_check = [x for x in doors_to_check if x.type in [DoorType.Normal, DoorType.Interior] and not x.blocked]
|
doors_to_check = [x for x in doors_to_check if x.type in [DoorType.Normal, DoorType.Interior] and not x.blocked]
|
||||||
for door in doors_to_check:
|
for door in doors_to_check:
|
||||||
@@ -1997,6 +2081,17 @@ bunny_impassible_doors = {
|
|||||||
'GT Validation Block Path'
|
'GT Validation Block Path'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bunny_impassible_if_trapped = {
|
||||||
|
'Hyrule Dungeon Armory Interior Key Door N', 'Eastern Pot Switch WN', 'Eastern Lobby NW',
|
||||||
|
'Eastern Lobby NE', 'Desert Compass Key Door WN', 'Tower Circle of Pots ES', 'PoD Mimics 2 SW',
|
||||||
|
'PoD Middle Cage S', 'Swamp Push Statue S', 'Skull 2 East Lobby WS', 'Skull Torch Room WS',
|
||||||
|
'Thieves Conveyor Maze WN', 'Thieves Conveyor Maze SW', 'Thieves Blocked Entry SW', 'Ice Bomb Jump NW',
|
||||||
|
'Ice Tall Hint EN', 'Ice Switch Room ES', 'Ice Switch Room NE', 'Mire Cross SW',
|
||||||
|
'Mire Tile Room SW', 'Mire Tile Room ES', 'TR Twin Pokeys NW', 'TR Torches WN', 'GT Hope Room WN',
|
||||||
|
'GT Speed Torch NE', 'GT Speed Torch WS', 'GT Torch Cross WN', 'GT Hidden Spikes SE', 'GT Conveyor Cross EN',
|
||||||
|
'GT Speed Torch WN', 'Ice Lobby SE'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def add_key_logic_rules(world, player):
|
def add_key_logic_rules(world, player):
|
||||||
key_logic = world.key_logic[player]
|
key_logic = world.key_logic[player]
|
||||||
|
|||||||
125
test/dungeons/trap_test.yaml
Normal file
125
test/dungeons/trap_test.yaml
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
meta:
|
||||||
|
players: 1
|
||||||
|
settings:
|
||||||
|
1:
|
||||||
|
door_shuffle: basic
|
||||||
|
intensity: 3
|
||||||
|
door_type_mode: all
|
||||||
|
doors:
|
||||||
|
1:
|
||||||
|
doors:
|
||||||
|
PoD Mimics 2 SW:
|
||||||
|
type: Trap Door
|
||||||
|
# TR Twin Pokeys NW: # not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
Thieves Blocked Entry SW:
|
||||||
|
type: Trap Door
|
||||||
|
Hyrule Dungeon Armory Interior Key Door N:
|
||||||
|
type: Trap Door
|
||||||
|
Desert Compass Key Door WN:
|
||||||
|
type: Trap Door
|
||||||
|
TR Tile Room SE:
|
||||||
|
type: Trap Door
|
||||||
|
# Mire Cross SW: # not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
Tower Circle of Pots ES:
|
||||||
|
type: Trap Door
|
||||||
|
Eastern Single Eyegore ES:
|
||||||
|
type: Trap Door
|
||||||
|
Eastern Duo Eyegores SE:
|
||||||
|
type: Trap Door
|
||||||
|
Swamp Push Statue S:
|
||||||
|
type: Trap Door
|
||||||
|
# Skull 2 East Lobby WS: # currently not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
GT Hope Room WN :
|
||||||
|
type: Trap Door
|
||||||
|
|
||||||
|
# Eastern Courtyard Ledge S: # currently not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
Ice Switch Room ES :
|
||||||
|
type: Trap Door
|
||||||
|
Ice Switch Room NE :
|
||||||
|
type: Trap Door
|
||||||
|
Skull Torch Room WS :
|
||||||
|
type: Trap Door
|
||||||
|
GT Speed Torch NE :
|
||||||
|
type: Trap Door
|
||||||
|
GT Speed Torch WS :
|
||||||
|
type: Trap Door
|
||||||
|
GT Torch Cross WN :
|
||||||
|
type: Trap Door
|
||||||
|
Mire Tile Room SW :
|
||||||
|
type: Trap Door
|
||||||
|
Mire Tile Room ES :
|
||||||
|
type: Trap Door
|
||||||
|
TR Torches WN :
|
||||||
|
type: Trap Door
|
||||||
|
PoD Lobby N:
|
||||||
|
type: Trap Door
|
||||||
|
PoD Middle Cage S:
|
||||||
|
type: Trap Door
|
||||||
|
Ice Bomb Jump NW:
|
||||||
|
type: Trap Door
|
||||||
|
GT Hidden Spikes SE:
|
||||||
|
type: Trap Door
|
||||||
|
Ice Tall Hint EN:
|
||||||
|
type: Trap Door
|
||||||
|
GT Conveyor Cross EN:
|
||||||
|
type: Trap Door
|
||||||
|
Eastern Pot Switch WN:
|
||||||
|
type: Trap Door
|
||||||
|
Thieves Conveyor Maze WN:
|
||||||
|
type: Trap Door
|
||||||
|
# Thieves Conveyor Maze SW: #not possible due to 4 door limit
|
||||||
|
# type: Trap Door
|
||||||
|
Eastern Dark Square Key Door WN:
|
||||||
|
type: Trap Door
|
||||||
|
Eastern Lobby NW:
|
||||||
|
type: Trap Door
|
||||||
|
Eastern Lobby NE:
|
||||||
|
type: Trap Door
|
||||||
|
# Ice Cross Bottom SE: # not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
Desert Back Lobby S:
|
||||||
|
type: Trap Door
|
||||||
|
# Desert West S: need enough lobbies for basic, should otherwise work
|
||||||
|
# type: Trap Door
|
||||||
|
Desert West Lobby ES:
|
||||||
|
type: Trap Door
|
||||||
|
# Mire Hidden Shooters SE: # not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
# Mire Hidden Shooters ES: # not possible due to trap flags
|
||||||
|
# type: Trap Door
|
||||||
|
Mire Hidden Shooters WS:
|
||||||
|
type: Trap Door
|
||||||
|
Tower Dark Pits EN:
|
||||||
|
type: Trap Door
|
||||||
|
Tower Dark Maze ES:
|
||||||
|
type: Trap Door
|
||||||
|
TR Tongue Pull WS:
|
||||||
|
type: Trap Door
|
||||||
|
|
||||||
|
# Lower layer: not valid
|
||||||
|
# Sewers Pull Switch N:
|
||||||
|
# type: Trap Door
|
||||||
|
# PoD Sexy Statue W: # not possible due to trap flags and low layer too, so likely not an exception
|
||||||
|
# type: Trap Door
|
||||||
|
|
||||||
|
# Not valid due to disappearing somaria block
|
||||||
|
# Mire Dark Shooters SE:
|
||||||
|
# type: Trap Door
|
||||||
|
|
||||||
|
# These triggers don't open doors
|
||||||
|
# Ice Compass Room NE:
|
||||||
|
# type: Trap Door
|
||||||
|
# Hera Torches NE:
|
||||||
|
# type: Trap Door
|
||||||
|
# Mire Spikes WS:
|
||||||
|
# type: Trap Door
|
||||||
|
# Mire Spikes SW:
|
||||||
|
# type: Trap Door
|
||||||
|
# Mire Spikes NW:
|
||||||
|
# type: Trap Door
|
||||||
|
# Tower Room 03 WN:
|
||||||
|
# type: Trap Door
|
||||||
Reference in New Issue
Block a user