Merged in DR v1.2.0.9
This commit is contained in:
@@ -129,7 +129,7 @@ def link_doors_prep(world, player):
|
||||
vanilla_key_logic(world, player)
|
||||
|
||||
|
||||
def link_doors_main(world, player):
|
||||
def create_dungeon_pool(world, player):
|
||||
pool = None
|
||||
if world.doorShuffle[player] == 'basic':
|
||||
pool = [([name], regions) for name, regions in dungeon_regions.items()]
|
||||
@@ -143,6 +143,11 @@ def link_doors_main(world, player):
|
||||
elif world.doorShuffle[player] != 'vanilla':
|
||||
logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player])
|
||||
raise Exception('Invalid door shuffle setting: %s' % world.doorShuffle[player])
|
||||
return pool
|
||||
|
||||
|
||||
def link_doors_main(world, player):
|
||||
pool = create_dungeon_pool(world, player)
|
||||
if pool:
|
||||
main_dungeon_pool(pool, world, player)
|
||||
if world.doorShuffle[player] != 'vanilla':
|
||||
@@ -558,7 +563,9 @@ def customizer_portals(master_door_list, world, player):
|
||||
custom_doors = world.customizer.get_doors()[player]
|
||||
if custom_doors and 'lobbies' in custom_doors:
|
||||
for portal, assigned_door in custom_doors['lobbies'].items():
|
||||
door = next(x for x in master_door_list if x.name == assigned_door)
|
||||
door = next((x for x in master_door_list if x.name == assigned_door), None)
|
||||
if door is None:
|
||||
raise Exception(f'{assigned_door} not found. Check for typos')
|
||||
custom_portals[portal] = door
|
||||
assigned_doors.add(door)
|
||||
if custom_doors and 'doors' in custom_doors:
|
||||
@@ -571,6 +578,24 @@ def customizer_portals(master_door_list, world, player):
|
||||
elif 'dest' in dest:
|
||||
door = world.get_door(dest['dest'], player)
|
||||
assigned_doors.add(door)
|
||||
# restricts connected doors to the customized portals
|
||||
if assigned_doors:
|
||||
pool = create_dungeon_pool(world, player)
|
||||
if pool:
|
||||
pool_map = {}
|
||||
for pool, region_list in pool:
|
||||
sector_pool = convert_to_sectors(region_list, world, player)
|
||||
merge_sectors(sector_pool, world, player)
|
||||
for p in pool:
|
||||
pool_map[p] = sector_pool
|
||||
for portal, assigned_door in custom_portals.items():
|
||||
portal_region = world.get_door(assigned_door, player).entrance.parent_region
|
||||
portal_dungeon = world.get_region(f'{portal} Portal', player).dungeon.name
|
||||
sector_pool = pool_map[portal_dungeon]
|
||||
sector = next((s for s in sector_pool if portal_region in s.regions), None)
|
||||
for door in sector.outstanding_doors:
|
||||
if door.portalAble:
|
||||
door.dungeonLink = portal_dungeon
|
||||
return custom_portals, assigned_doors
|
||||
|
||||
|
||||
@@ -1719,7 +1744,6 @@ def setup_custom_door_types(world, player):
|
||||
custom_doors = custom_doors[player]
|
||||
if 'doors' not in custom_doors:
|
||||
return
|
||||
# todo: dash/bomb door pool specific
|
||||
customizeable_types = ['Key Door', 'Dash Door', 'Bomb Door', 'Trap Door', 'Big Key Door']
|
||||
world.custom_door_types[player] = type_map = {x: defaultdict(list) for x in customizeable_types}
|
||||
for door, dest in custom_doors['doors'].items():
|
||||
@@ -1732,7 +1756,7 @@ def setup_custom_door_types(world, player):
|
||||
type_map[door_kind][dungeon.name].append(d)
|
||||
else:
|
||||
# check if the dest is paired
|
||||
if d.dest.type in [DoorType.Interior, DoorType.Normal] and door_kind != 'Trap Door':
|
||||
if d.dest and d.dest.type in [DoorType.Interior, DoorType.Normal] and door_kind != 'Trap Door':
|
||||
type_map[door_kind][dungeon.name].append((d, d.dest))
|
||||
else:
|
||||
type_map[door_kind][dungeon.name].append(d)
|
||||
@@ -1784,18 +1808,24 @@ def shuffle_door_types(door_type_pools, paths, world, player):
|
||||
start_regions_map[name] = start_regions
|
||||
builder.candidates = BuilderDoorCandidates()
|
||||
|
||||
all_custom = defaultdict(list)
|
||||
if player in world.custom_door_types:
|
||||
for custom_dict in world.custom_door_types[player].values():
|
||||
for dungeon, doors in custom_dict.items():
|
||||
all_custom[dungeon].extend(doors)
|
||||
|
||||
world.paired_doors[player].clear()
|
||||
used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player)
|
||||
used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, world, player)
|
||||
# big keys
|
||||
used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player)
|
||||
used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player)
|
||||
# small keys
|
||||
used_doors = shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player)
|
||||
used_doors = shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player)
|
||||
# bombable / dashable
|
||||
used_doors = shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, world, player)
|
||||
used_doors = shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player)
|
||||
# handle paired list
|
||||
|
||||
|
||||
def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player):
|
||||
def shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, world, player):
|
||||
used_doors = set()
|
||||
for pool, door_type_pool in door_type_pools:
|
||||
if world.trap_door_mode[player] != 'oneway':
|
||||
@@ -1806,15 +1836,14 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player)
|
||||
custom_trap_doors = world.custom_door_types[player]['Trap Door']
|
||||
else:
|
||||
custom_trap_doors = defaultdict(list)
|
||||
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
if 'Mire Warping Pool' in builder.master_sector.region_set():
|
||||
custom_trap_doors[dungeon].append(world.get_door('Mire Warping Pool ES', player))
|
||||
world.custom_door_types[player]['Trap Door'] = custom_trap_doors
|
||||
find_trappable_candidates(builder, world, player)
|
||||
if custom_trap_doors[dungeon]:
|
||||
builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon])
|
||||
if all_custom[dungeon]:
|
||||
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:
|
||||
@@ -1866,7 +1895,7 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player)
|
||||
return used_doors
|
||||
|
||||
|
||||
def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player):
|
||||
def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player):
|
||||
for pool, door_type_pool in door_type_pools:
|
||||
ttl = 0
|
||||
suggestion_map, bk_map, flex_map = {}, {}, {}
|
||||
@@ -1879,8 +1908,8 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world,
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
find_big_key_candidates(builder, start_regions_map[dungeon], used_doors, world, player)
|
||||
if custom_bk_doors[dungeon]:
|
||||
builder.candidates.big = filter_key_door_pool(builder.candidates.big, custom_bk_doors[dungeon])
|
||||
if all_custom[dungeon]:
|
||||
builder.candidates.big = filter_key_door_pool(builder.candidates.big, all_custom[dungeon])
|
||||
remaining -= len(custom_bk_doors[dungeon])
|
||||
ttl += len(builder.candidates.big)
|
||||
if ttl == 0:
|
||||
@@ -1926,7 +1955,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world,
|
||||
return used_doors
|
||||
|
||||
|
||||
def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player):
|
||||
def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player):
|
||||
max_computation = 11 # this is around 6 billion worse case factorial don't want to exceed this much
|
||||
for pool, door_type_pool in door_type_pools:
|
||||
ttl = 0
|
||||
@@ -1944,8 +1973,8 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
builder.total_keys = total_keys
|
||||
find_small_key_door_candidates(builder, start_regions_map[dungeon], used_doors, world, player)
|
||||
custom_doors = 0
|
||||
if custom_key_doors[dungeon]:
|
||||
builder.candidates.small = filter_key_door_pool(builder.candidates.small, custom_key_doors[dungeon])
|
||||
if all_custom[dungeon]:
|
||||
builder.candidates.small = filter_key_door_pool(builder.candidates.small, all_custom[dungeon])
|
||||
custom_doors = len(custom_key_doors[dungeon])
|
||||
remaining -= custom_doors
|
||||
builder.key_doors_num = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + custom_doors
|
||||
@@ -1961,13 +1990,10 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
suggested = min(calculated, limit)
|
||||
key_door_num = min(suggested + builder.key_drop_cnt, max_computation)
|
||||
combo_size = ncr(len(builder.candidates.small), key_door_num)
|
||||
while combo_size > 500000 and suggested > 0:
|
||||
suggested -= 1
|
||||
combo_size = ncr(len(builder.candidates.small), key_door_num)
|
||||
suggestion_map[dungeon] = builder.key_doors_num = key_door_num
|
||||
remaining -= suggested + builder.key_drop_cnt
|
||||
remaining -= key_door_num + builder.key_drop_cnt
|
||||
builder.combo_size = combo_size
|
||||
flex_map[dungeon] = (limit - suggested) if suggested < limit else 0
|
||||
flex_map[dungeon] = (limit - key_door_num) if key_door_num < limit else 0
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
if total_adjustable:
|
||||
@@ -2026,7 +2052,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
return used_doors
|
||||
|
||||
|
||||
def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, world, player):
|
||||
def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player):
|
||||
for pool, door_type_pool in door_type_pools:
|
||||
ttl = 0
|
||||
suggestion_map, bd_map = {}, {}
|
||||
@@ -2043,11 +2069,9 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
find_bd_candidates(builder, start_regions_map[dungeon], used_doors, world, player)
|
||||
if custom_bomb_doors[dungeon]:
|
||||
builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, custom_bomb_doors[dungeon])
|
||||
if all_custom[dungeon]:
|
||||
builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, all_custom[dungeon])
|
||||
remaining_bomb -= len(custom_bomb_doors[dungeon])
|
||||
if custom_dash_doors[dungeon]:
|
||||
builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, custom_dash_doors[dungeon])
|
||||
remaining_dash -= len(custom_dash_doors[dungeon])
|
||||
ttl += len(builder.candidates.bomb_dash)
|
||||
if ttl == 0:
|
||||
|
||||
Reference in New Issue
Block a user