diff --git a/DoorShuffle.py b/DoorShuffle.py index b2a2df6c..4433714d 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -552,7 +552,7 @@ def customizer_portals(master_door_list, world, player): if isinstance(dest, str): door = world.get_door(dest, player) assigned_doors.add(door) - else: + elif 'dest' in dest: door = world.get_door(dest['dest'], player) assigned_doors.add(door) return custom_portals, assigned_doors @@ -1709,8 +1709,8 @@ def setup_custom_door_types(world, player): if d.type == DoorType.SpiralStairs: type_map[door_kind][dungeon.name].append(d) else: - # check if the - if d.dest.type in [DoorType.Interior, DoorType.Normal]: + # check if the dest is paired + if 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) @@ -1853,10 +1853,11 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, ttl += len(builder.candidates.big) if ttl == 0: continue + remaining = max(0, remaining) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.big) - calc = int(round(proportion * door_type_pool.bigs/ttl)) + calc = int(round(proportion * remaining/ttl)) suggested = min(proportion, calc) remaining -= suggested suggestion_map[dungeon] = suggested @@ -1910,12 +1911,15 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl if not total_adjustable: 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]) - remaining -= len(custom_key_doors[dungeon]) - builder.key_doors_num = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + 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 total_keys -= builder.key_drop_cnt ttl += builder.key_doors_num + remaining = max(0, remaining) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] calculated = int(round(builder.key_doors_num*total_keys/ttl)) @@ -1923,7 +1927,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl cand_len = max(0, len(builder.candidates.small) - builder.key_drop_cnt) limit = min(max_keys, cand_len, max_computation) suggested = min(calculated, limit) - key_door_num = min(suggested + builder.key_drop_cnt, max_computation) + 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 @@ -2143,6 +2147,7 @@ def find_valid_trap_combination(builder, suggested, start_regions, paths, world, if custom_trap_doors: trap_door_pool = filter_key_door_pool(trap_door_pool, custom_trap_doors) trap_doors_needed -= len(custom_trap_doors) + trap_doors_needed = max(0, trap_doors_needed) if len(trap_door_pool) < trap_doors_needed: if not drop: return None, 0 @@ -2421,6 +2426,7 @@ def find_valid_bk_combination(builder, suggested, start_regions, world, player, if custom_bk_doors: bk_door_pool = filter_key_door_pool(bk_door_pool, custom_bk_doors) bk_doors_needed -= len(custom_bk_doors) + bk_doors_needed = max(0, bk_doors_needed) if len(bk_door_pool) < bk_doors_needed: if not drop: return None, 0 @@ -2560,7 +2566,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k if custom_key_doors: # could validate that each custom item is in the candidates key_door_pool = filter_key_door_pool(key_door_pool, custom_key_doors) key_doors_needed -= len(custom_key_doors) - + key_doors_needed = max(0, key_doors_needed) # find valid combination of candidates if len(key_door_pool) < key_doors_needed: if not drop_keys: @@ -2575,6 +2581,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k sample_list = build_sample_list(combinations) proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) proposal.extend(custom_key_doors) + builder.key_doors_num = len(proposal) start_regions, event_starts = filter_start_regions(builder, start_regions, world, player) key_layout = build_key_layout(builder, start_regions, proposal, event_starts, world, player) @@ -2607,7 +2614,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k builder.key_door_proposal = proposal world.key_logic[player][builder.name] = key_layout.key_logic world.key_layout[player][builder.name] = key_layout - return builder.key_door_proposal, key_doors_needed + return builder.key_door_proposal, key_doors_needed + len(custom_key_doors) def find_bd_candidates(builder, start_regions, used, world, player): diff --git a/Doors.py b/Doors.py index 7c9e5ca6..110ca5c9 100644 --- a/Doors.py +++ b/Doors.py @@ -1473,6 +1473,8 @@ def create_doors(world, player): world.get_door('GT Spike Crystal Right to Left Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('GT Spike Crystal Left to Right Bypass', player).barrier(CrystalBarrier.Blue) + world.get_door('Sanctuary Mirror Route', player).barrier(CrystalBarrier.Orange) + # kill certain doors if world.intensity[player] == 1: # due to ladder & warp being fixed world.get_door('PoD Mimics 2 SW', player).kill() diff --git a/ItemList.py b/ItemList.py index a07d2b2b..45007237 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1541,7 +1541,8 @@ def fill_specific_items(world): world.push_item(loc, item_to_place, False) track_outside_keys(item_to_place, loc, world) track_dungeon_items(item_to_place, loc, world) - loc.event = event_flag or item_to_place.advancement + loc.event = (event_flag or item_to_place.advancement + or item_to_place.bigkey or item_to_place.smallkey) advanced_placements = world.customizer.get_advanced_placements() if advanced_placements: for player, placement_list in advanced_placements.items(): diff --git a/Main.py b/Main.py index b7af0523..e15e66ae 100644 --- a/Main.py +++ b/Main.py @@ -35,7 +35,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.4-u' +__version__ = '1.2.0.5-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 54b2edb0..095682e0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,6 +108,9 @@ These are now independent of retro mode and have three options: None, Random, an * Bonk Fairy (Dark) # Bug Fixes and Notes +* 1.2.0.5.u + * Logic fix for Sanctuary mirror (it wasn't resetting the crystal state) + * Minor bugfixes for customizer * 1.2.0.4-u * Starting inventory fixes if item not present in the item pool. * Support for Assured sword setting and OWG Boots when using a custom item pool. (Customizer or GUI) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index abcd9da8..e35e1e78 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -311,7 +311,7 @@ def do_main_shuffle(entrances, exits, avail, mode_def): unused_entrances.update(lw_entrances) unused_entrances.update(dw_entrances) else: - entrance_list = [x for x in rem_entrances if bonk_fairy_exception(x)] + entrance_list = sorted([x for x in rem_entrances if bonk_fairy_exception(x)]) do_cross_world_connectors(entrance_list, multi_exit_caves, avail) unused_entrances.update(entrance_list)