AHIT: Add option to shuffle Battle of the Birds director tokens and time bonus pickups (#5400)

This commit is contained in:
CookieCat
2026-01-31 14:09:31 -05:00
committed by GitHub
parent c47687dd21
commit 77e5f3733e
3 changed files with 47 additions and 2 deletions

View File

@@ -63,6 +63,9 @@ def is_location_valid(world: "HatInTimeWorld", location: str) -> bool:
if not world.options.ShuffleStorybookPages and location in storybook_pages.keys():
return False
if not world.options.ShuffleDirectorTokens and location in director_tokens.keys():
return False
if not world.options.ShuffleActContracts and location in contract_locations.keys():
return False
@@ -566,6 +569,34 @@ storybook_pages = {
"Rumbi Factory - Page: Last Area": LocData(2000345883, "Time Rift - Rumbi Factory", dlc_flags=HatDLC.dlc2),
}
director_tokens = {
"Murder on the Owl Express - Conductor Token: Cafeteria": LocData(2001104767, "Murder on the Owl Express"),
"Murder on the Owl Express - Conductor Token: Recreational Room": LocData(2001104768, "Murder on the Owl Express"),
"Picture Perfect - DJ Grooves Token: Cardboard Puppy": LocData(2001203990, "Picture Perfect"),
"Picture Perfect - DJ Grooves Token: Card Guessing Game": LocData(2001203991, "Picture Perfect"),
"Picture Perfect - DJ Grooves Token: Back Alley": LocData(2001203992, "Picture Perfect"),
"Picture Perfect - DJ Grooves Token: Cooking Show": LocData(2001203993, "Picture Perfect"),
"Picture Perfect - DJ Grooves Token: Pon Cluster": LocData(2001203987, "Picture Perfect"),
"Train Rush - Time Bonus: 1st Room": LocData(2001305235, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Falling Platform": LocData(2001305189, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Acid Crates": LocData(2001305186, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Balloon": LocData(2001305239, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Ring of Fire": LocData(2001305237, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Blue Panels": LocData(2001305236, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Sinking Lava Platform": LocData(2001305234, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Lava Panels 1": LocData(2001305193, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Lava Panels 2": LocData(2001305190, "Train Rush", hookshot=True),
"Train Rush - Time Bonus: Lava Panels 3": LocData(2001305238, "Train Rush", hookshot=True),
"The Big Parade - DJ Grooves Token (1/8)": LocData(2001400000, "The Big Parade"),
"The Big Parade - DJ Grooves Token (2/8)": LocData(2001400001, "The Big Parade"),
"The Big Parade - DJ Grooves Token (3/8)": LocData(2001400002, "The Big Parade"),
"The Big Parade - DJ Grooves Token (4/8)": LocData(2001400003, "The Big Parade"),
"The Big Parade - DJ Grooves Token (5/8)": LocData(2001400004, "The Big Parade", hit_type=HitType.umbrella),
"The Big Parade - DJ Grooves Token (6/8)": LocData(2001400005, "The Big Parade", hit_type=HitType.umbrella),
"The Big Parade - DJ Grooves Token (7/8)": LocData(2001400006, "The Big Parade", hit_type=HitType.umbrella),
"The Big Parade - DJ Grooves Token (8/8)": LocData(2001400007, "The Big Parade", hit_type=HitType.umbrella),
}
shop_locations = {
"Badge Seller - Item 1": LocData(2000301003, "Badge Seller"),
"Badge Seller - Item 2": LocData(2000301004, "Badge Seller"),
@@ -1050,6 +1081,7 @@ location_table = {
**ahit_locations,
**act_completions,
**storybook_pages,
**director_tokens,
**contract_locations,
**shop_locations,
}

View File

@@ -72,6 +72,7 @@ def adjust_options(world: "HatInTimeWorld"):
world.options.EndGoal.value = EndGoal.option_seal_the_deal
world.options.ActRandomizer.value = 0
world.options.ShuffleAlpineZiplines.value = 0
world.options.ShuffleDirectorTokens.value = 0
world.options.ShuffleSubconPaintings.value = 0
world.options.ShuffleStorybookPages.value = 0
world.options.ShuffleActContracts.value = 0
@@ -219,6 +220,12 @@ class ShuffleStorybookPages(DefaultOnToggle):
display_name = "Shuffle Storybook Pages"
class ShuffleDirectorTokens(Toggle):
"""If enabled, causes the Conductor/DJ Grooves tokens found in Chapter 2 levels to become item checks.
NOTE: This also includes the time bonus pickups from Train Rush, since the level doesn't have any tokens."""
display_name = "Shuffle Director Tokens"
class ShuffleActContracts(DefaultOnToggle):
"""If enabled, shuffle Snatcher's act contracts into the pool as items"""
display_name = "Shuffle Contracts"
@@ -658,6 +665,7 @@ class AHITOptions(PerGameCommonOptions):
StartWithCompassBadge: StartWithCompassBadge
CompassBadgeMode: CompassBadgeMode
ShuffleStorybookPages: ShuffleStorybookPages
ShuffleDirectorTokens: ShuffleDirectorTokens
ShuffleActContracts: ShuffleActContracts
ShuffleSubconPaintings: ShuffleSubconPaintings
NoPaintingSkips: NoPaintingSkips
@@ -722,7 +730,8 @@ class AHITOptions(PerGameCommonOptions):
ahit_option_groups: Dict[str, List[Any]] = {
"General Options": [EndGoal, ShuffleStorybookPages, ShuffleAlpineZiplines, ShuffleSubconPaintings,
"General Options": [EndGoal, ShuffleStorybookPages, ShuffleDirectorTokens,
ShuffleAlpineZiplines, ShuffleSubconPaintings,
ShuffleActContracts, MinPonCost, MaxPonCost, BadgeSellerMinItems, BadgeSellerMaxItems,
LogicDifficulty, NoPaintingSkips, CTRLogic],
@@ -759,6 +768,7 @@ slot_data_options: List[str] = [
"StartWithCompassBadge",
"CompassBadgeMode",
"ShuffleStorybookPages",
"ShuffleDirectorTokens",
"ShuffleActContracts",
"ShuffleSubconPaintings",
"NoPaintingSkips",

View File

@@ -1,7 +1,7 @@
from BaseClasses import Region, Entrance, ItemClassification, Location, LocationProgressType
from .Types import ChapterIndex, Difficulty, HatInTimeLocation, HatInTimeItem
from .Locations import location_table, storybook_pages, event_locs, is_location_valid, \
shop_locations, TASKSANITY_START_ID, snatcher_coins, zero_jumps, zero_jumps_expert, zero_jumps_hard
shop_locations, TASKSANITY_START_ID, snatcher_coins, zero_jumps, zero_jumps_expert, zero_jumps_hard, director_tokens
from typing import TYPE_CHECKING, List, Dict, Optional
from .Rules import set_rift_rules, get_difficulty
from .Options import ActRandomizer, EndGoal
@@ -859,6 +859,9 @@ def create_region(world: "HatInTimeWorld", name: str) -> Region:
if key in storybook_pages.keys() and not world.options.ShuffleStorybookPages:
continue
if key in director_tokens.keys() and not world.options.ShuffleDirectorTokens:
continue
location = HatInTimeLocation(world.player, key, data.id, reg)
reg.locations.append(location)
if location.name in shop_locations: