Timespinner: Update AP to have parity with standalone options (#3805)

This commit is contained in:
Ehseezed 2024-11-29 13:46:12 -06:00 committed by GitHub
parent b605fb1032
commit 77d35b95e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 38 additions and 7 deletions

View File

@ -199,7 +199,11 @@ item_table: Dict[str, ItemData] = {
'Chaos Trap': ItemData('Trap', 1337186, 0, trap=True), 'Chaos Trap': ItemData('Trap', 1337186, 0, trap=True),
'Neurotoxin Trap': ItemData('Trap', 1337187, 0, trap=True), 'Neurotoxin Trap': ItemData('Trap', 1337187, 0, trap=True),
'Bee Trap': ItemData('Trap', 1337188, 0, trap=True), 'Bee Trap': ItemData('Trap', 1337188, 0, trap=True),
# 1337189 - 1337248 Reserved 'Laser Access A': ItemData('Relic', 1337189, progression=True),
'Laser Access I': ItemData('Relic', 1337191, progression=True),
'Laser Access M': ItemData('Relic', 1337192, progression=True),
'Throw Stun Trap': ItemData('Trap', 1337193, 0, trap=True),
# 1337194 - 1337248 Reserved
'Max Sand': ItemData('Stat', 1337249, 14) 'Max Sand': ItemData('Stat', 1337249, 14)
} }

View File

@ -71,8 +71,8 @@ def get_location_datas(player: Optional[int], options: Optional[TimespinnerOptio
LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton', 1337044), LocationData('Skeleton Shaft', 'Sealed Caves (Xarion): Skeleton', 1337044),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom jump room', 1337045, logic.has_timestop), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Shroom jump room', 1337045, logic.has_timestop),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Double shroom room', 1337046), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Double shroom room', 1337046),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Mini jackpot room', 1337047, logic.has_forwarddash_doublejump), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Jacksquat room', 1337047, logic.has_forwarddash_doublejump),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Below mini jackpot room', 1337048), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Below Jacksquat room', 1337048),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Secret room', 1337049, logic.can_break_walls), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Secret room', 1337049, logic.can_break_walls),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Bottom left room', 1337050), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Bottom left room', 1337050),
LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last chance before Xarion', 1337051, logic.has_doublejump), LocationData('Sealed Caves (Xarion)', 'Sealed Caves (Xarion): Last chance before Xarion', 1337051, logic.has_doublejump),

View File

@ -22,6 +22,7 @@ class TimespinnerLogic:
self.flag_specific_keycards = bool(options and options.specific_keycards) self.flag_specific_keycards = bool(options and options.specific_keycards)
self.flag_eye_spy = bool(options and options.eye_spy) self.flag_eye_spy = bool(options and options.eye_spy)
self.flag_unchained_keys = bool(options and options.unchained_keys) self.flag_unchained_keys = bool(options and options.unchained_keys)
self.flag_prism_break = bool(options and options.prism_break)
if precalculated_weights: if precalculated_weights:
if self.flag_unchained_keys: if self.flag_unchained_keys:
@ -92,6 +93,8 @@ class TimespinnerLogic:
return True return True
def can_kill_all_3_bosses(self, state: CollectionState) -> bool: def can_kill_all_3_bosses(self, state: CollectionState) -> bool:
if self.flag_prism_break:
return state.has_all({'Laser Access M', 'Laser Access I', 'Laser Access A'}, self.player)
return state.has_all({'Killed Maw', 'Killed Twins', 'Killed Aelana'}, self.player) return state.has_all({'Killed Maw', 'Killed Twins', 'Killed Aelana'}, self.player)
def has_teleport(self, state: CollectionState) -> bool: def has_teleport(self, state: CollectionState) -> bool:

View File

@ -180,12 +180,19 @@ class DamageRandoOverrides(OptionDict):
} }
class HpCap(Range): class HpCap(Range):
"Sets the number that Lunais's HP maxes out at." """Sets the number that Lunais's HP maxes out at."""
display_name = "HP Cap" display_name = "HP Cap"
range_start = 1 range_start = 1
range_end = 999 range_end = 999
default = 999 default = 999
class AuraCap(Range):
"""Sets the maximum Aura Lunais is allowed to have. Level 1 is 80. Djinn Inferno costs 45."""
display_name = "Aura Cap"
range_start = 45
range_end = 999
default = 999
class LevelCap(Range): class LevelCap(Range):
"""Sets the max level Lunais can achieve.""" """Sets the max level Lunais can achieve."""
display_name = "Level Cap" display_name = "Level Cap"
@ -359,13 +366,18 @@ class TrapChance(Range):
class Traps(OptionList): class Traps(OptionList):
"""List of traps that may be in the item pool to find""" """List of traps that may be in the item pool to find"""
display_name = "Traps Types" display_name = "Traps Types"
valid_keys = { "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap" } valid_keys = { "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap" }
default = [ "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap" ] default = [ "Meteor Sparrow Trap", "Poison Trap", "Chaos Trap", "Neurotoxin Trap", "Bee Trap", "Throw Stun Trap" ]
class PresentAccessWithWheelAndSpindle(Toggle): class PresentAccessWithWheelAndSpindle(Toggle):
"""When inverted, allows using the refugee camp warp when both the Timespinner Wheel and Spindle is acquired.""" """When inverted, allows using the refugee camp warp when both the Timespinner Wheel and Spindle is acquired."""
display_name = "Back to the future" display_name = "Back to the future"
class PrismBreak(Toggle):
"""Adds 3 Laser Access items to the item pool to remove the lasers blocking the military hangar area
instead of needing to beat the Golden Idol, Aelana, and The Maw."""
display_name = "Prism Break"
@dataclass @dataclass
class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin): class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin):
start_with_jewelry_box: StartWithJewelryBox start_with_jewelry_box: StartWithJewelryBox
@ -383,6 +395,7 @@ class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin):
damage_rando: DamageRando damage_rando: DamageRando
damage_rando_overrides: DamageRandoOverrides damage_rando_overrides: DamageRandoOverrides
hp_cap: HpCap hp_cap: HpCap
aura_cap: AuraCap
level_cap: LevelCap level_cap: LevelCap
extra_earrings_xp: ExtraEarringsXP extra_earrings_xp: ExtraEarringsXP
boss_healing: BossHealing boss_healing: BossHealing
@ -401,6 +414,7 @@ class TimespinnerOptions(PerGameCommonOptions, DeathLinkMixin):
rising_tides_overrides: RisingTidesOverrides rising_tides_overrides: RisingTidesOverrides
unchained_keys: UnchainedKeys unchained_keys: UnchainedKeys
back_to_the_future: PresentAccessWithWheelAndSpindle back_to_the_future: PresentAccessWithWheelAndSpindle
prism_break: PrismBreak
trap_chance: TrapChance trap_chance: TrapChance
traps: Traps traps: Traps

View File

@ -102,6 +102,7 @@ class TimespinnerWorld(World):
"DamageRando": self.options.damage_rando.value, "DamageRando": self.options.damage_rando.value,
"DamageRandoOverrides": self.options.damage_rando_overrides.value, "DamageRandoOverrides": self.options.damage_rando_overrides.value,
"HpCap": self.options.hp_cap.value, "HpCap": self.options.hp_cap.value,
"AuraCap": self.options.aura_cap.value,
"LevelCap": self.options.level_cap.value, "LevelCap": self.options.level_cap.value,
"ExtraEarringsXP": self.options.extra_earrings_xp.value, "ExtraEarringsXP": self.options.extra_earrings_xp.value,
"BossHealing": self.options.boss_healing.value, "BossHealing": self.options.boss_healing.value,
@ -119,6 +120,7 @@ class TimespinnerWorld(World):
"RisingTides": self.options.rising_tides.value, "RisingTides": self.options.rising_tides.value,
"UnchainedKeys": self.options.unchained_keys.value, "UnchainedKeys": self.options.unchained_keys.value,
"PresentAccessWithWheelAndSpindle": self.options.back_to_the_future.value, "PresentAccessWithWheelAndSpindle": self.options.back_to_the_future.value,
"PrismBreak": self.options.prism_break.value,
"Traps": self.options.traps.value, "Traps": self.options.traps.value,
"DeathLink": self.options.death_link.value, "DeathLink": self.options.death_link.value,
"StinkyMaw": True, "StinkyMaw": True,
@ -224,6 +226,9 @@ class TimespinnerWorld(World):
elif name in {"Timeworn Warp Beacon", "Modern Warp Beacon", "Mysterious Warp Beacon"} \ elif name in {"Timeworn Warp Beacon", "Modern Warp Beacon", "Mysterious Warp Beacon"} \
and not self.options.unchained_keys: and not self.options.unchained_keys:
item.classification = ItemClassification.filler item.classification = ItemClassification.filler
elif name in {"Laser Access A", "Laser Access I", "Laser Access M"} \
and not self.options.prism_break:
item.classification = ItemClassification.filler
return item return item
@ -256,6 +261,11 @@ class TimespinnerWorld(World):
excluded_items.add('Modern Warp Beacon') excluded_items.add('Modern Warp Beacon')
excluded_items.add('Mysterious Warp Beacon') excluded_items.add('Mysterious Warp Beacon')
if not self.options.prism_break:
excluded_items.add('Laser Access A')
excluded_items.add('Laser Access I')
excluded_items.add('Laser Access M')
for item in self.multiworld.precollected_items[self.player]: for item in self.multiworld.precollected_items[self.player]:
if item.name not in self.item_name_groups['UseItem']: if item.name not in self.item_name_groups['UseItem']:
excluded_items.add(item.name) excluded_items.add(item.name)