diff --git a/DoorShuffle.py b/DoorShuffle.py index f4ee9cfa..b2156357 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1791,12 +1791,30 @@ def stateful_door(door, kind): return False +dashable_forbidden = { + 'Swamp Trench 1 Key Ledge NW', 'Swamp Left Elbow WN', 'Swamp Right Elbow SE', 'Mire Hub WN', 'Mire Hub WS', + 'Mire Hub Top NW', 'Mire Hub NE', 'Ice Dead End WS' +} + +ohko_forbidden = { + 'GT Invisible Catwalk NE', 'GT Falling Bridge WN', 'GT Falling Bridge WS', 'GT Hidden Star ES', 'GT Hookshot EN', + 'GT Torch Cross WN', 'TR Torches WN', 'Mire Falling Bridge WS', 'Mire Falling Bridge W', 'Ice Hookshot Balcony SW', + 'Ice Catwalk WN', 'Ice Catwalk NW', 'Ice Bomb Jump NW', 'GT Cannonball Bridge SE' +} + + +def filter_dashable_candidates(candidates, world): + forbidden_set = dashable_forbidden if world.can_take_damage else ohko_forbidden + return [x for x in candidates if x not in forbidden_set and x.dest not in forbidden_set] + + def shuffle_bombable_dashable(bd_candidates, world, player): if world.doorShuffle[player] == 'basic': for dungeon, candidates in bd_candidates.items(): diff = bomb_dash_counts[dungeon.name][1] if diff > 0: - for chosen in random.sample(candidates, min(diff, len(candidates))): + dash_candidates = filter_dashable_candidates(candidates, world) + for chosen in random.sample(dash_candidates, min(diff, len(candidates))): change_pair_type(chosen, DoorKind.Dashable, world, player) candidates.remove(chosen) diff = bomb_dash_counts[dungeon.name][0] @@ -1808,7 +1826,8 @@ def shuffle_bombable_dashable(bd_candidates, world, player): remove_pair_type_if_present(excluded, world, player) elif world.doorShuffle[player] == 'crossed': all_candidates = sum(bd_candidates.values(), []) - for chosen in random.sample(all_candidates, min(8, len(all_candidates))): + dash_candidates = filter_dashable_candidates(all_candidates, world) + for chosen in random.sample(dash_candidates, min(8, len(all_candidates))): change_pair_type(chosen, DoorKind.Dashable, world, player) all_candidates.remove(chosen) for chosen in random.sample(all_candidates, min(12, len(all_candidates))): diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 07c498f2..1d99f310 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -153,6 +153,7 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o * Inverted bug * Fix for hammerdashing pots, if sprite limit is reached, items won't spawn, error beep won't play either because of other SFX * Killing enemies freeze + hammer results in the droppable item instead of the freeze prize + * Forbid certain doors from being dashable when you either can't dash them open (but bombs would work) or you'd fall into a pit from the recoil in OHKO * 1.0.1.11 * Separated Collection Rate counter from experimental * Added MSU Resume option diff --git a/Rules.py b/Rules.py index e96a483a..7f9c0802 100644 --- a/Rules.py +++ b/Rules.py @@ -736,9 +736,10 @@ def pot_rules(world, player): for l in world.get_region('Palace of Darkness Hint', player).locations: if l.type == LocationType.Pot: add_rule(l, lambda state: state.can_use_bombs(player) or state.has_Boots(player)) - for l in world.get_region('Dark Lake Hylia Ledge Spike Cave', player).locations: - if l.type == LocationType.Pot: - add_rule(l, lambda state: state.world.can_take_damage or state.has('Hookshot', player) + for number in ['1', '2']: + loc = world.get_location_unsafe(f'Dark Lake Hylia Ledge Spike Cave Pot #{number}', player) + if loc and loc.type == LocationType.Pot: + add_rule(loc, lambda state: state.world.can_take_damage or state.has('Hookshot', player) or state.has('Cape', player) or (state.has('Cane of Byrna', player) and state.world.difficulty_adjustments[player] == 'normal'))