Logic added for openable trap doors

This commit is contained in:
aerinon
2023-08-03 15:06:54 -06:00
parent c0c3204fd5
commit f442cff061
6 changed files with 271 additions and 15 deletions

View File

@@ -88,8 +88,7 @@ def link_doors_prep(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':
choose_portals(world, player)
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])
remaining -= len(custom_trap_doors[dungeon])
ttl += len(builder.candidates.trap)
if ttl == 0:
if ttl == 0 and all(len(custom_trap_doors[dungeon]) == 0 for dungeon in pool):
continue
for dungeon in pool:
builder = world.dungeon_layouts[player][dungeon]
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)
remaining -= 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)
for dungeon in pool:
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))
cand_len = max(0, len(builder.candidates.small) - builder.key_drop_cnt)
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)
proposal = kth_combination(sample_list[itr], trap_door_pool, trap_doors_needed)
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)
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
if itr >= len(sample_list):
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
if portal_entrance_region not in builder.path_entrances:
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'):
excluded[region] = None
if portal is None:
@@ -2343,10 +2352,12 @@ def reassign_trap_doors(trap_map, world, player):
elif kind in [DoorKind.Trap2, DoorKind.TrapTriggerable]:
room.change(d.doorListPos, DoorKind.Normal)
d.blocked = False
d.trapped = False
# connect_one_way(world, d.name, d.dest.name, player)
elif d.type is DoorType.Normal and d not in traps:
world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal)
d.blocked = False
d.trapped = False
for d in traps:
change_door_to_trap(d, world, 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]:
new_kind = DoorKind.TrapTriggerable
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
verify_door_list_pos(d, room, world, player, pos)
d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1, 3: 0x8}[d.doorListPos]
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 = None
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)
d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos]
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 = 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):
if world.door_type_mode[player] != 'original': # big, all, chaos
# traverse dungeon and find candidates