[Timespinner] New seed options and new locations checks (#140)
This commit is contained in:
parent
b3ae4b86e4
commit
8363d1749b
|
@ -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>
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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, ...] = (
|
||||
|
|
|
@ -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)
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue