[Timespinner] New seed options and new locations checks (#140)

This commit is contained in:
Jarno Westhof 2021-11-28 22:59:34 +01:00 committed by GitHub
parent b3ae4b86e4
commit 8363d1749b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 100 additions and 56 deletions

View File

@ -38,26 +38,29 @@
<td><img src="{{ icons['Gas Mask'] }}" class="{{ 'acquired' if 'Gas Mask' in acquired_items }}" title="Gas Mask" /></td>
</tr>
<tr>
{% if 'Fire Orb' in acquired_items %}
<td><img src="{{ icons['Kobo'] }}" class="{{ 'acquired' if 'Kobo' in acquired_items }}" title="Kobo" /></td>
<td><img src="{{ icons['Merchant Crow'] }}" class="{{ 'acquired' if 'Merchant Crow' in acquired_items }}" title="Merchant Crow" /></td>
{% if 'Djinn Inferno' in acquired_items %}
<td><img src="{{ icons['Djinn Inferno'] }}" class="acquired" title="Djinn Inferno" /></td>
{% elif 'Pyro Ring' in acquired_items %}
<td><img src="{{ icons['Pyro Ring'] }}" class="acquired" title="Pyro Ring" /></td>
{% elif 'Fire Orb' in acquired_items %}
<td><img src="{{ icons['Fire Orb'] }}" class="acquired" title="Fire Orb" /></td>
{% elif 'Infernal Flames' in acquired_items %}
<td><img src="{{ icons['Infernal Flames'] }}" class="acquired" title="Infernal Flames" /></td>
{% elif 'Pyro Ring' in acquired_items %}
<td><img src="{{ icons['Pyro Ring'] }}" class="acquired" title="Pyro Ring" /></td>
{% elif 'Pyro Ring' in acquired_items %}
<td><img src="{{ icons['Djinn Inferno'] }}" class="acquired" title="Djinn Inferno" /></td>
{% else %}
<td><img src="{{ icons['Fire Orb'] }}" title="Fire Orb" /></td>
<td><img src="{{ icons['Djinn Inferno'] }}" title="Djinn Inferno" /></td>
{% endif %}
{% if 'Plasma Orb' in acquired_items %}
<td><img src="{{ icons['Plasma Orb'] }}" class="acquired" title="Plasma Orb" /></td>
{% if 'Royal Ring' in acquired_items %}
<td><img src="{{ icons['Royal Ring'] }}" class="acquired" title="Royal Ring" /></td>
{% elif 'Plasma Geyser' in acquired_items %}
<td><img src="{{ icons['Plasma Geyser'] }}" class="acquired" title="Plasma Geyser" /></td>
{% elif 'Royal Ring' in acquired_items %}
<td><img src="{{ icons['Royal Ring'] }}" class="acquired" title="Royal Ring" /></td>
{% elif 'Plasma Orb' in acquired_items %}
<td><img src="{{ icons['Plasma Orb'] }}" class="acquired" title="Plasma Orb" /></td>
{% else %}
<td><img src="{{ icons['Plasma Orb'] }}" title="Plasma Orb" /></td>
<td><img src="{{ icons['Royal Ring'] }}" title="Royal Ring" /></td>
{% endif %}
</tr>
</table>

View File

@ -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]
}

View File

@ -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),

View File

@ -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, ...] = (

View File

@ -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)
return self.has_all({'Killed Maw', 'Killed Twins', 'Killed Aelana'}, player)

View File

@ -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,
}

View File

@ -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))

View File

@ -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