From 8363d1749b7e5975e9b24454664cd843ed68ad79 Mon Sep 17 00:00:00 2001 From: Jarno Westhof Date: Sun, 28 Nov 2021 22:59:34 +0100 Subject: [PATCH] [Timespinner] New seed options and new locations checks (#140) --- WebHostLib/templates/timespinnerTracker.html | 25 ++++--- WebHostLib/tracker.py | 7 +- worlds/timespinner/Items.py | 14 ++-- worlds/timespinner/Locations.py | 70 ++++++++++++++------ worlds/timespinner/LogicMixin.py | 20 +++--- worlds/timespinner/Options.py | 10 +++ worlds/timespinner/Regions.py | 2 +- worlds/timespinner/__init__.py | 8 ++- 8 files changed, 100 insertions(+), 56 deletions(-) diff --git a/WebHostLib/templates/timespinnerTracker.html b/WebHostLib/templates/timespinnerTracker.html index 197b844d..f8d9c453 100644 --- a/WebHostLib/templates/timespinnerTracker.html +++ b/WebHostLib/templates/timespinnerTracker.html @@ -38,26 +38,29 @@ - {% if 'Fire Orb' in acquired_items %} + + + + {% if 'Djinn Inferno' in acquired_items %} + + {% elif 'Pyro Ring' in acquired_items %} + + {% elif 'Fire Orb' in acquired_items %} {% elif 'Infernal Flames' in acquired_items %} - {% elif 'Pyro Ring' in acquired_items %} - - {% elif 'Pyro Ring' in acquired_items %} - {% else %} - + {% endif %} - {% if 'Plasma Orb' in acquired_items %} - + {% if 'Royal Ring' in acquired_items %} + {% elif 'Plasma Geyser' in acquired_items %} - {% elif 'Royal Ring' in acquired_items %} - + {% elif 'Plasma Orb' in acquired_items %} + {% else %} - + {% endif %} diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 47def5ec..567257bf 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -712,6 +712,8 @@ def __renderTimespinnerTracker(multisave: Dict[str, Any], room: Room, locations: "Royal Ring": "https://timespinnerwiki.com/mediawiki/images/f/f3/Royal_Ring.png", "Plasma Geyser": "https://timespinnerwiki.com/mediawiki/images/1/12/Plasma_Geyser.png", "Plasma Orb": "https://timespinnerwiki.com/mediawiki/images/4/44/Plasma_Orb.png", + "Kobo": "https://timespinnerwiki.com/mediawiki/images/c/c6/Familiar_Kobo.png", + "Merchant Crow": "https://timespinnerwiki.com/mediawiki/images/4/4e/Familiar_Crow.png", } timespinner_location_ids = { @@ -726,7 +728,7 @@ def __renderTimespinnerTracker(multisave: Dict[str, Any], room: Room, locations: 1337070, 1337071, 1337072, 1337073, 1337074, 1337075, 1337076, 1337077, 1337078, 1337079, 1337080, 1337081, 1337082, 1337083, 1337084, 1337085, 1337156, 1337157, 1337159, 1337160, 1337161, 1337162, 1337163, 1337164, 1337165, 1337166, 1337167, 1337168, 1337169, - 1337170], + 1337170, 1337237, 1337238], "Past": [ 1337086, 1337087, 1337088, 1337089, 1337090, 1337091, 1337092, 1337093, 1337094, 1337095, 1337096, 1337097, 1337098, 1337099, @@ -735,7 +737,8 @@ def __renderTimespinnerTracker(multisave: Dict[str, Any], room: Room, locations: 1337120, 1337121, 1337122, 1337123, 1337124, 1337125, 1337126, 1337127, 1337128, 1337129, 1337130, 1337131, 1337132, 1337133, 1337134, 1337135, 1337136, 1337137, 1337138, 1337139, 1337140, 1337141, 1337142, 1337143, 1337144, 1337145, 1337146, 1337147, 1337148, 1337149, - 1337150, 1337151, 1337152, 1337153, 1337154, 1337155], + 1337150, 1337151, 1337152, 1337153, 1337154, 1337155, + 1337171, 1337172, 1337173, 1337174, 1337175, 1337176], "Ancient Pyramid": [1337246, 1337247, 1337248, 1337249] } diff --git a/worlds/timespinner/Items.py b/worlds/timespinner/Items.py index ada37630..82958eba 100644 --- a/worlds/timespinner/Items.py +++ b/worlds/timespinner/Items.py @@ -24,9 +24,9 @@ item_table: Dict[str, ItemData] = { 'Lab Glasses': ItemData('Equipment', 1337012), 'Empire Crown': ItemData('Equipment', 1337013), 'Viletian Crown': ItemData('Equipment', 1337014), - 'Sunglasses': ItemData('Equipment', 1337015, 0), + 'Sunglasses': ItemData('Equipment', 1337015), 'Old Coat': ItemData('Equipment', 1337016), - 'Trendy Jacket': ItemData('Equipment', 1337017, 0), + 'Trendy Jacket': ItemData('Equipment', 1337017), 'Security Vest': ItemData('Equipment', 1337018, 0), 'Leather Jerkin': ItemData('Equipment', 1337019, 0), 'Copper Breastplate': ItemData('Equipment', 1337020, 0), @@ -53,15 +53,15 @@ item_table: Dict[str, ItemData] = { 'Filigree Clasp': ItemData('Equipment', 1337041), 'Azure Stole': ItemData('Equipment', 1337042, 0), 'Ancient Coin': ItemData('Equipment', 1337043), - 'Shiny Rock': ItemData('Equipment', 1337044, 0), + 'Shiny Rock': ItemData('Equipment', 1337044), 'Galaxy Earrings': ItemData('Equipment', 1337045, never_exclude=True), 'Selen\'s Bangle': ItemData('Equipment', 1337046, never_exclude=True), 'Glass Pumpkin': ItemData('Equipment', 1337047, never_exclude=True), 'Gilded Egg': ItemData('Equipment', 1337048, never_exclude=True), 'Meyef': ItemData('Familiar', 1337049), 'Griffin': ItemData('Familiar', 1337050), - 'Merchant Crow': ItemData('Familiar', 1337051), - 'Kobo': ItemData('Familiar', 1337052), + 'Merchant Crow': ItemData('Familiar', 1337051, progression=True), + 'Kobo': ItemData('Familiar', 1337052, progression=True), 'Sprite': ItemData('Familiar', 1337053), 'Demon': ItemData('Familiar', 1337054), 'Potion': ItemData('UseItem', 1337055, 0), @@ -93,7 +93,7 @@ item_table: Dict[str, ItemData] = { 'Filigree Tea': ItemData('UseItem', 1337081), 'Empress Cake': ItemData('UseItem', 1337082, 0), 'Rotten Tail': ItemData('UseItem', 1337083, 0), - 'Alchemy Tools': ItemData('UseItem', 1337084, 0), + 'Alchemy Tools': ItemData('UseItem', 1337084), 'Galaxy Stone': ItemData('UseItem', 1337085), # 1337086 Used interally 'Essence Crystal': ItemData('UseItem', 1337087, 0), @@ -101,7 +101,7 @@ item_table: Dict[str, ItemData] = { 'Gold Necklace': ItemData('UseItem', 1337089, 0), 'Herb': ItemData('UseItem', 1337090), 'Mushroom': ItemData('UseItem', 1337091, 0), - 'Plasma Crystal': ItemData('UseItem', 1337092, 0), + 'Plasma Crystal': ItemData('UseItem', 1337092), 'Plasma IV Bag': ItemData('UseItem', 1337093), 'Cheveur Drumstick': ItemData('UseItem', 1337094, 0), 'Wyvern Tail': ItemData('UseItem', 1337095, 0), diff --git a/worlds/timespinner/Locations.py b/worlds/timespinner/Locations.py index 5cc107da..921e215e 100644 --- a/worlds/timespinner/Locations.py +++ b/worlds/timespinner/Locations.py @@ -1,4 +1,4 @@ -from typing import Tuple, Optional, Callable, NamedTuple +from typing import List, Tuple, Optional, Callable, NamedTuple from BaseClasses import MultiWorld from .Options import is_option_enabled @@ -11,7 +11,7 @@ class LocationData(NamedTuple): rule: Callable = lambda state: True def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[LocationData, ...]: - location_table: Tuple[LocationData, ...] = ( + location_table: List[LocationData] = [ # PresentItemLocations LocationData('Tutorial', 'Yo Momma 1', 1337000), LocationData('Tutorial', 'Yo Momma 2', 1337001), @@ -29,8 +29,8 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L LocationData('Upper lake desolation', 'Upper desolation double jump cave platform', 1337013), LocationData('Upper lake desolation', 'Fire-Locked sparrow chest', 1337014), LocationData('Upper lake desolation', 'Crash site pedestal', 1337015), - LocationData('Upper lake desolation', 'Crash site chest 1', 1337016, lambda state: state.has_all(['Killed Maw', 'Gas Mask'], player)), - LocationData('Upper lake desolation', 'Crash site chest 2', 1337017, lambda state: state.has_all(['Killed Maw', 'Gas Mask'], player)), + LocationData('Upper lake desolation', 'Crash site chest 1', 1337016, lambda state: state.has_all({'Killed Maw', 'Gas Mask'}, player)), + LocationData('Upper lake desolation', 'Crash site chest 2', 1337017, lambda state: state.has_all({'Killed Maw', 'Gas Mask'}, player)), LocationData('Upper lake desolation', 'Kitty Boss', 1337018), LocationData('Library', 'Library Basement', 1337019), LocationData('Library', 'Library warp gate', 1337020), @@ -118,8 +118,10 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L LocationData('Upper Lake Serene', 'Upper Serene double jump cave platform', 1337100, lambda state: state._timespinner_has_doublejump(world, player)), LocationData('Upper Lake Serene', 'Upper Serene double jump cave floor', 1337101), LocationData('Upper Lake Serene', 'Upper Serene cave secret', 1337102, lambda state: state._timespinner_can_break_walls(world, player)), + LocationData('Upper Lake Serene', 'Before Big Bird', 1337175), LocationData('Upper Lake Serene', 'Serene behind the vines', 1337103), LocationData('Upper Lake Serene', 'Pyramid keys room', 1337104), + LocationData('Upper Lake Serene', 'Chicken ledge', 1337174), LocationData('Lower Lake Serene', 'Deep dive', 1337105), LocationData('Lower Lake Serene', 'Under the eels', 1337106), LocationData('Lower Lake Serene', 'Water spikes room', 1337107), @@ -137,12 +139,14 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L LocationData('Caves of Banishment (upper)', 'Banishment jackpot room chest 4', 1337119, lambda state: state._timespinner_has_forwarddash_doublejump(world, player)), LocationData('Caves of Banishment (upper)', 'Banishment pedestal', 1337120), LocationData('Caves of Banishment (Maw)', 'Last chance before Maw', 1337121, lambda state: state._timespinner_has_doublejump(world, player)), + LocationData('Caves of Banishment (Maw)', 'Plasma Crystal', 1337173, lambda state: state.has_any({'Gas Mask', 'Talaria Attachment'}, player)), LocationData('Caves of Banishment (Maw)', 'Killed Maw', EventId, lambda state: state.has('Gas Mask', player)), LocationData('Caves of Banishment (Maw)', 'Mineshaft', 1337122, lambda state: state.has('Gas Mask', player)), LocationData('Caves of Banishment (Sirens)', 'Wyvern room', 1337123), LocationData('Caves of Banishment (Sirens)', 'Upper banishment above sirens', 1337124), LocationData('Caves of Banishment (Sirens)', 'Under banishment sirens left', 1337125, lambda state: state.has('Water Mask', player)), LocationData('Caves of Banishment (Sirens)', 'Under banishment sirens right', 1337126, lambda state: state.has('Water Mask', player)), + LocationData('Caves of Banishment (Sirens)', 'Underwater banishment sirens right ground', 1337172, lambda state: state.has('Water Mask', player)), LocationData('Caves of Banishment (Sirens)', 'Banishment water hook', 1337127, lambda state: state.has('Water Mask', player)), LocationData('Castle Ramparts', 'Castle bomber chest', 1337128, lambda state: state._timespinner_has_multiple_small_jumps_of_npc(world, player)), LocationData('Castle Ramparts', 'Ramparts Freeze the engineer', 1337129, lambda state: state.has('Talaria Attachment', player) or state._timespinner_has_timestop(world, player)), @@ -157,6 +161,7 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L LocationData('Castle Keep', 'Just an egg', 1337138), LocationData('Castle Keep', 'Under the twins', 1337139), LocationData('Castle Keep', 'Killed Twins', EventId, lambda state: state._timespinner_has_timestop(world, player)), + LocationData('Castle Keep', 'Advisor jump', 1337171, lambda state: state._timespinner_has_timestop(world, player)), LocationData('Castle Keep', 'Twins', 1337140, lambda state: state._timespinner_has_timestop(world, player)), LocationData('Castle Keep', 'Royal guard tiny room', 1337141, lambda state: state._timespinner_has_doublejump(world, player) or state._timespinner_has_fastjump_on_npc(world,player)), LocationData('Royal towers (lower)', 'Royal tower floor secret', 1337142, lambda state: state._timespinner_has_doublejump(world, player) and state._timespinner_can_break_walls(world, player)), @@ -175,34 +180,35 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L LocationData('Royal towers (upper)', 'Aelana\'s pedestal', 1337154), LocationData('Royal towers (upper)', 'Aelana\'s chest', 1337155), - # 1337157 - 1337170 Downloads + # 1337176 - 1337176 Cantoran - # 1337171 - 1337238 Reserved + # 1337177 - 1337236 Reserved + + # 1337237 - 1337238 GyreArchives # PyramidItemLocations - #LocationData('Temporal Gyre', 'Transition chest 1', 1337239), - #LocationData('Temporal Gyre', 'Transition chest 2', 1337240), - #LocationData('Temporal Gyre', 'Transition chest 3', 1337241), - #LocationData('Temporal Gyre', 'Ravenlord pre fight', 1337242), - #LocationData('Temporal Gyre', 'Ravenlord post fight', 1337243), - #LocationData('Temporal Gyre', 'Ifrid pre fight', 1337244), - #LocationData('Temporal Gyre', 'Ifrid post fight', 1337245), + LocationData('Ancient Pyramid (right)', 'Transition chest 1', 1337239), + LocationData('Ancient Pyramid (right)', 'Transition chest 2', 1337240), + LocationData('Ancient Pyramid (right)', 'Transition chest 3', 1337241), + + # 1337242 - 1337245 GyreArchives + LocationData('Ancient Pyramid (left)', 'Why not it\'s right there', 1337246), LocationData('Ancient Pyramid (left)', 'Conviction guarded room', 1337247), LocationData('Ancient Pyramid (right)', 'Pit secret room', 1337248, lambda state: state._timespinner_can_break_walls(world, player)), LocationData('Ancient Pyramid (right)', 'Regret chest', 1337249, lambda state: state._timespinner_can_break_walls(world, player)), LocationData('Ancient Pyramid (right)', 'Killed Nightmare', EventId) - ) + ] - downloadable_items: Tuple[LocationData, ...] = ( + downloadable_locations: Tuple[LocationData, ...] = ( # DownloadTerminals LocationData('Library', 'Library terminal 1', 1337157, lambda state: state.has('Tablet', player)), LocationData('Library', 'Library terminal 2', 1337156, lambda state: state.has('Tablet', player)), # 1337158 Is Lost in time LocationData('Library', 'Library terminal 3', 1337159, lambda state: state.has('Tablet', player)), - LocationData('Library', 'V terminal 1', 1337160, lambda state: state.has_all(['Tablet', 'Library Keycard V'], player)), - LocationData('Library', 'V terminal 2', 1337161, lambda state: state.has_all(['Tablet', 'Library Keycard V'], player)), - LocationData('Library', 'V terminal 3', 1337162, lambda state: state.has_all(['Tablet', 'Library Keycard V'], player)), + LocationData('Library', 'V terminal 1', 1337160, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), + LocationData('Library', 'V terminal 2', 1337161, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), + LocationData('Library', 'V terminal 3', 1337162, lambda state: state.has_all({'Tablet', 'Library Keycard V'}, player)), LocationData('Library top', 'Backer room terminal', 1337163, lambda state: state.has('Tablet', player)), LocationData('Varndagroth tower right (elevator)', 'Medbay', 1337164, lambda state: state.has('Tablet', player) and state._timespinner_has_keycard_B(world, player)), LocationData('The lab (upper)', 'Chest and download terminal', 1337165, lambda state: state.has('Tablet', player)), @@ -213,10 +219,30 @@ def get_locations(world: Optional[MultiWorld], player: Optional[int]) -> Tuple[L LocationData('The lab (power off)', 'Lab terminal right', 1337170, lambda state: state.has('Tablet', player)) ) - if not world or is_option_enabled(world, player, "DownloadableItems"): - return ( *location_table, *downloadable_items ) - else: - return location_table + gyre_archives_locations: Tuple[LocationData, ...] = ( + LocationData('The lab (upper)', 'Ravenlord post fight (pedestal)', 1337237, lambda state: state.has('Merchant Crow', player)), + LocationData('Library top', 'Ifrit post fight (pedestal)', 1337238, lambda state: state.has('Kobo', player)), + LocationData('The lab (upper)', 'Ravenlord pre fight', 1337242, lambda state: state.has('Merchant Crow', player)), + LocationData('The lab (upper)', 'Ravenlord post fight (chest)', 1337243, lambda state: state.has('Merchant Crow', player)), + LocationData('Library top', 'Ifrit pre fight', 1337244, lambda state: state.has('Kobo', player)), + LocationData('Library top', 'Ifrit post fight (chest)', 1337245, lambda state: state.has('Kobo', player)), + ) + + cantoran_locations: Tuple[LocationData, ...] = ( + LocationData('Left Side forest Caves', 'Cantoran', 1337176), + ) + + if not world: + return ( *location_table, *downloadable_locations, *gyre_archives_locations, *cantoran_locations ) + + if is_option_enabled(world, player, "DownloadableItems"): + location_table.extend(downloadable_locations) + if is_option_enabled(world, player, "GyreArchives"): + location_table.extend(gyre_archives_locations) + if is_option_enabled(world, player, "Cantoran"): + location_table.extend(cantoran_locations) + + return tuple(location_table) starter_progression_locations: Tuple[str, ...] = ( diff --git a/worlds/timespinner/LogicMixin.py b/worlds/timespinner/LogicMixin.py index 7a81c25e..df7e8f6b 100644 --- a/worlds/timespinner/LogicMixin.py +++ b/worlds/timespinner/LogicMixin.py @@ -4,10 +4,10 @@ from .Options import is_option_enabled class TimespinnerLogic(LogicMixin): def _timespinner_has_timestop(self, world: MultiWorld, player: int) -> bool: - return self.has_any(['Timespinner Wheel', 'Succubus Hairpin', 'Lightwall', 'Celestial Sash'], player) + return self.has_any({'Timespinner Wheel', 'Succubus Hairpin', 'Lightwall', 'Celestial Sash'}, player) def _timespinner_has_doublejump(self, world: MultiWorld, player: int) -> bool: - return self.has_any(['Succubus Hairpin', 'Lightwall', 'Celestial Sash'], player) + return self.has_any({'Succubus Hairpin', 'Lightwall', 'Celestial Sash'}, player) def _timespinner_has_forwarddash_doublejump(self, world: MultiWorld, player: int) -> bool: return self._timespinner_has_upwarddash(world, player) or (self.has('Talaria Attachment', player) and self._timespinner_has_doublejump(world, player)) @@ -16,19 +16,19 @@ class TimespinnerLogic(LogicMixin): return self._timespinner_has_upwarddash(world, player) or (self.has('Timespinner Wheel', player) and self._timespinner_has_doublejump(world, player)) def _timespinner_has_fastjump_on_npc(self, world: MultiWorld, player: int) -> bool: - return self.has_all(['Timespinner Wheel', 'Talaria Attachment'], player) + return self.has_all({'Timespinner Wheel', 'Talaria Attachment'}, player) def _timespinner_has_multiple_small_jumps_of_npc(self, world: MultiWorld, player: int) -> bool: return self.has('Timespinner Wheel', player) or self._timespinner_has_upwarddash(world, player) def _timespinner_has_upwarddash(self, world: MultiWorld, player: int) -> bool: - return self.has_any(['Lightwall', 'Celestial Sash'], player) + return self.has_any({'Lightwall', 'Celestial Sash'}, player) def _timespinner_has_fire(self, world: MultiWorld, player: int) -> bool: - return self.has_any(['Fire Orb', 'Infernal Flames', 'Pyro Ring', 'Djinn Inferno'], player) + return self.has_any({'Fire Orb', 'Infernal Flames', 'Pyro Ring', 'Djinn Inferno'}, player) def _timespinner_has_pink(self, world: MultiWorld, player: int) -> bool: - return self.has_any(['Plasma Orb', 'Plasma Geyser', 'Royal Ring'], player) + return self.has_any({'Plasma Orb', 'Plasma Geyser', 'Royal Ring'}, player) def _timespinner_has_keycard_A(self, world: MultiWorld, player: int) -> bool: return self.has('Security Keycard A', player) @@ -37,19 +37,19 @@ class TimespinnerLogic(LogicMixin): if is_option_enabled(world, player, "SpecificKeycards"): return self.has('Security Keycard B', player) else: - return self.has_any(['Security Keycard A', 'Security Keycard B'], player) + return self.has_any({'Security Keycard A', 'Security Keycard B'}, player) def _timespinner_has_keycard_C(self, world: MultiWorld, player: int) -> bool: if is_option_enabled(world, player, "SpecificKeycards"): return self.has('Security Keycard C', player) else: - return self.has_any(['Security Keycard A', 'Security Keycard B', 'Security Keycard C'], player) + return self.has_any({'Security Keycard A', 'Security Keycard B', 'Security Keycard C'}, player) def _timespinner_has_keycard_D(self, world: MultiWorld, player: int) -> bool: if is_option_enabled(world, player, "SpecificKeycards"): return self.has('Security Keycard D', player) else: - return self.has_any(['Security Keycard A', 'Security Keycard B', 'Security Keycard C', 'Security Keycard D'], player) + return self.has_any({'Security Keycard A', 'Security Keycard B', 'Security Keycard C', 'Security Keycard D'}, player) def _timespinner_can_break_walls(self, world: MultiWorld, player: int) -> bool: if is_option_enabled(world, player, "FacebookMode"): @@ -58,4 +58,4 @@ class TimespinnerLogic(LogicMixin): return True def _timespinner_can_kill_all_3_bosses(self, world: MultiWorld, player: int) -> bool: - return self.has_all(['Killed Maw', 'Killed Twins', 'Killed Aelana'], player) \ No newline at end of file + return self.has_all({'Killed Maw', 'Killed Twins', 'Killed Aelana'}, player) \ No newline at end of file diff --git a/worlds/timespinner/Options.py b/worlds/timespinner/Options.py index 60573145..d3a848c6 100644 --- a/worlds/timespinner/Options.py +++ b/worlds/timespinner/Options.py @@ -42,6 +42,14 @@ class Inverted(Toggle): # "Require gasmask for Maw" # display_name = "Stinky Maw" +class GyreArchives(Toggle): + "Gyre locations are in logic. New warps are gated by Merchant Crow and Kobo" + display_name = "Gyre Archives" + +class Cantoran(Toggle): + "Cantoran's fight and check are available upon revisiting his room" + display_name = "Cantoran" + # Some options that are available in the timespinner randomizer arent currently implemented timespinner_options: Dict[str, Toggle] = { "StartWithJewelryBox": StartWithJewelryBox, @@ -54,6 +62,8 @@ timespinner_options: Dict[str, Toggle] = { "SpecificKeycards": SpecificKeycards, "Inverted": Inverted, #"StinkyMaw": StinkyMaw, + "GyreArchives": GyreArchives, + "Cantoran": Cantoran, "DeathLink": DeathLink, } diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index 7fa1ec27..b59b8b8c 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -88,7 +88,7 @@ def create_regions(world: MultiWorld, player: int, locations: Tuple[LocationData connect(world, player, names, 'The lab (power off)', 'The lab (upper)', lambda state: state._timespinner_has_forwarddash_doublejump(world, player)) connect(world, player, names, 'The lab (upper)', 'The lab (power off)') connect(world, player, names, 'The lab (upper)', 'Emperors tower', lambda state: state._timespinner_has_forwarddash_doublejump(world, player)) - connect(world, player, names, 'The lab (upper)', 'Ancient Pyramid (left)', lambda state: state.has_all(['Timespinner Wheel', 'Timespinner Spindle', 'Timespinner Gear 1', 'Timespinner Gear 2', 'Timespinner Gear 3'], player)) + connect(world, player, names, 'The lab (upper)', 'Ancient Pyramid (left)', lambda state: state.has_all({'Timespinner Wheel', 'Timespinner Spindle', 'Timespinner Gear 1', 'Timespinner Gear 2', 'Timespinner Gear 3'}, player)) connect(world, player, names, 'Emperors tower', 'The lab (upper)') connect(world, player, names, 'Skeleton Shaft', 'Lake desolation') connect(world, player, names, 'Skeleton Shaft', 'Sealed Caves (upper)', lambda state: state._timespinner_has_keycard_A(world, player)) diff --git a/worlds/timespinner/__init__.py b/worlds/timespinner/__init__.py index 4a982ff2..b0602f18 100644 --- a/worlds/timespinner/__init__.py +++ b/worlds/timespinner/__init__.py @@ -18,7 +18,7 @@ class TimespinnerWorld(World): game = "Timespinner" topology_present = True remote_items = False - data_version = 3 + data_version = 4 item_name_to_id = {name: data.code for name, data in item_table.items()} location_name_to_id = {location.name: location.code for location in get_locations(None, None)} @@ -92,7 +92,7 @@ def get_excluded_items_based_on_options(world: MultiWorld, player: int) -> Set[s excluded_items.add('Meyef') if is_option_enabled(world, player, "QuickSeed"): excluded_items.add('Talaria Attachment') - + return excluded_items @@ -155,7 +155,9 @@ def create_item_with_correct_settings(world: MultiWorld, player: int, name: str) if (name == 'Tablet' or name == 'Library Keycard V') and not is_option_enabled(world, player, "DownloadableItems"): item.advancement = False - if name == 'Oculus Ring' and not is_option_enabled(world, player, "FacebookMode"): + elif name == 'Oculus Ring' and not is_option_enabled(world, player, "FacebookMode"): + item.advancement = False + elif (name == 'Kobo' or name == 'Merchant Crow') and not is_option_enabled(world, player, "GyreArchives"): item.advancement = False return item