diff --git a/worlds/ahit/DeathWishRules.py b/worlds/ahit/DeathWishRules.py index 1432ef5c..76723d39 100644 --- a/worlds/ahit/DeathWishRules.py +++ b/worlds/ahit/DeathWishRules.py @@ -141,9 +141,12 @@ def set_dw_rules(world: "HatInTimeWorld"): add_dw_rules(world, all_clear) add_rule(main_stamp, main_objective.access_rule) add_rule(all_clear, main_objective.access_rule) - # Only set bonus stamp rules if we don't auto complete bonuses + # Only set bonus stamp rules to require All Clear if we don't auto complete bonuses if not world.options.DWAutoCompleteBonuses and not world.is_bonus_excluded(all_clear.name): add_rule(bonus_stamps, all_clear.access_rule) + else: + # As soon as the Main Objective is completed, the bonuses auto-complete. + add_rule(bonus_stamps, main_objective.access_rule) if world.options.DWShuffle: for i in range(len(world.dw_shuffle)-1): @@ -343,6 +346,7 @@ def create_enemy_events(world: "HatInTimeWorld"): def set_enemy_rules(world: "HatInTimeWorld"): no_tourist = "Camera Tourist" in world.excluded_dws or "Camera Tourist" in world.excluded_bonuses + difficulty = get_difficulty(world) for enemy, regions in hit_list.items(): if no_tourist and enemy in bosses: @@ -372,6 +376,14 @@ def set_enemy_rules(world: "HatInTimeWorld"): or state.has("Zipline Unlock - The Lava Cake Path", world.player) or state.has("Zipline Unlock - The Windmill Path", world.player)) + elif enemy == "Toilet": + if area == "Toilet of Doom": + # The boss firewall is in the way and can only be skipped on Expert logic using a cherry hover. + add_rule(event, lambda state: has_paintings(state, world, 1, allow_skip=difficulty == Difficulty.EXPERT)) + if difficulty < Difficulty.HARD: + # Hard logic and above can cross the boss arena gap with a cherry bridge. + add_rule(event, lambda state: can_use_hookshot(state, world)) + elif enemy == "Director": if area == "Dead Bird Studio Basement": add_rule(event, lambda state: can_use_hookshot(state, world)) @@ -430,7 +442,7 @@ hit_list = { # Bosses "Mafia Boss": ["Down with the Mafia!", "Encore! Encore!", "Boss Rush"], - "Conductor": ["Dead Bird Studio Basement", "Killing Two Birds", "Boss Rush"], + "Director": ["Dead Bird Studio Basement", "Killing Two Birds", "Boss Rush"], "Toilet": ["Toilet of Doom", "Boss Rush"], "Snatcher": ["Your Contract has Expired", "Breaching the Contract", "Boss Rush", @@ -454,7 +466,7 @@ triple_enemy_locations = [ bosses = [ "Mafia Boss", - "Conductor", + "Director", "Toilet", "Snatcher", "Toxic Flower", diff --git a/worlds/ahit/Locations.py b/worlds/ahit/Locations.py index 9954514e..b34e6bb4 100644 --- a/worlds/ahit/Locations.py +++ b/worlds/ahit/Locations.py @@ -264,7 +264,6 @@ ahit_locations = { required_hats=[HatType.DWELLER], paintings=3), "Subcon Forest - Tall Tree Hookshot Swing": LocData(2000324766, "Subcon Forest Area", - required_hats=[HatType.DWELLER], hookshot=True, paintings=3), @@ -323,7 +322,7 @@ ahit_locations = { "Alpine Skyline - The Twilight Path": LocData(2000334434, "Alpine Skyline Area", required_hats=[HatType.DWELLER]), "Alpine Skyline - The Twilight Bell: Wide Purple Platform": LocData(2000336478, "The Twilight Bell"), "Alpine Skyline - The Twilight Bell: Ice Platform": LocData(2000335826, "The Twilight Bell"), - "Alpine Skyline - Goat Outpost Horn": LocData(2000334760, "Alpine Skyline Area"), + "Alpine Skyline - Goat Outpost Horn": LocData(2000334760, "Alpine Skyline Area (TIHS)", hookshot=True), "Alpine Skyline - Windy Passage": LocData(2000334776, "Alpine Skyline Area (TIHS)", hookshot=True), "Alpine Skyline - The Windmill: Inside Pon Cluster": LocData(2000336395, "The Windmill"), "Alpine Skyline - The Windmill: Entrance": LocData(2000335783, "The Windmill"), @@ -407,7 +406,7 @@ act_completions = { hit_type=HitType.umbrella_or_brewing, hookshot=True, paintings=1), "Act Completion (Queen Vanessa's Manor)": LocData(2000312017, "Queen Vanessa's Manor", - hit_type=HitType.umbrella, paintings=1), + hit_type=HitType.dweller_bell, paintings=1), "Act Completion (Mail Delivery Service)": LocData(2000312032, "Mail Delivery Service", required_hats=[HatType.SPRINT]), @@ -878,7 +877,7 @@ snatcher_coins = { dlc_flags=HatDLC.death_wish), "Snatcher Coin - Top of HQ (DW: BTH)": LocData(0, "Beat the Heat", snatcher_coin="Snatcher Coin - Top of HQ", - dlc_flags=HatDLC.death_wish), + hit_type=HitType.umbrella, dlc_flags=HatDLC.death_wish), "Snatcher Coin - Top of Tower": LocData(0, "Mafia Town Area (HUMT)", snatcher_coin="Snatcher Coin - Top of Tower", dlc_flags=HatDLC.death_wish), diff --git a/worlds/ahit/Rules.py b/worlds/ahit/Rules.py index 183248a0..6753b8eb 100644 --- a/worlds/ahit/Rules.py +++ b/worlds/ahit/Rules.py @@ -414,7 +414,7 @@ def set_moderate_rules(world: "HatInTimeWorld"): # Moderate: Mystifying Time Mesa time trial without hats set_rule(world.multiworld.get_location("Alpine Skyline - Mystifying Time Mesa: Zipline", world.player), - lambda state: can_use_hookshot(state, world)) + lambda state: True) # Moderate: Goat Refinery from TIHS with Sprint only add_rule(world.multiworld.get_location("Alpine Skyline - Goat Refinery", world.player), @@ -493,9 +493,6 @@ def set_hard_rules(world: "HatInTimeWorld"): lambda state: has_paintings(state, world, 3, True)) # SDJ - add_rule(world.multiworld.get_location("Subcon Forest - Long Tree Climb Chest", world.player), - lambda state: can_use_hat(state, world, HatType.SPRINT) and has_paintings(state, world, 2), "or") - add_rule(world.multiworld.get_location("Act Completion (Time Rift - Curly Tail Trail)", world.player), lambda state: can_use_hat(state, world, HatType.SPRINT), "or") @@ -533,7 +530,10 @@ def set_expert_rules(world: "HatInTimeWorld"): # Expert: Mafia Town - Above Boats, Top of Lighthouse, and Hot Air Balloon with nothing set_rule(world.multiworld.get_location("Mafia Town - Above Boats", world.player), lambda state: True) set_rule(world.multiworld.get_location("Mafia Town - Top of Lighthouse", world.player), lambda state: True) - set_rule(world.multiworld.get_location("Mafia Town - Hot Air Balloon", world.player), lambda state: True) + # There are not enough buckets/beach balls to bucket/ball hover in Heating Up Mafia Town, so any other Mafia Town + # act is required. + add_rule(world.multiworld.get_location("Mafia Town - Hot Air Balloon", world.player), + lambda state: state.can_reach_region("Mafia Town Area", world.player), "or") # Expert: Clear Dead Bird Studio with nothing for loc in world.multiworld.get_region("Dead Bird Studio - Post Elevator Area", world.player).locations: @@ -590,7 +590,7 @@ def set_expert_rules(world: "HatInTimeWorld"): if world.is_dlc2(): # Expert: clear Rush Hour with nothing - if not world.options.NoTicketSkips: + if world.options.NoTicketSkips != NoTicketSkips.option_true: set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player), lambda state: True) else: set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player), @@ -739,7 +739,7 @@ def set_dlc1_rules(world: "HatInTimeWorld"): # This particular item isn't present in Act 3 for some reason, yes in vanilla too add_rule(world.multiworld.get_location("The Arctic Cruise - Toilet", world.player), - lambda state: state.can_reach("Bon Voyage!", "Region", world.player) + lambda state: (state.can_reach("Bon Voyage!", "Region", world.player) and can_use_hookshot(state, world)) or state.can_reach("Ship Shape", "Region", world.player))