| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  | from typing import Dict, TYPE_CHECKING | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-10 15:30:20 -05:00
										 |  |  | from BaseClasses import CollectionState | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  | from worlds.generic.Rules import CollectionRule, add_rule, allow_self_locking_items | 
					
						
							| 
									
										
										
										
											2023-10-08 07:33:39 -05:00
										 |  |  | from .constants import NOTES, PHOBEKINS | 
					
						
							| 
									
										
										
										
											2023-11-10 22:49:55 -06:00
										 |  |  | from .options import MessengerAccessibility | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | if TYPE_CHECKING: | 
					
						
							|  |  |  |     from . import MessengerWorld | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MessengerRules: | 
					
						
							|  |  |  |     player: int | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |     world: "MessengerWorld" | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     connection_rules: Dict[str, CollectionRule] | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |     region_rules: Dict[str, CollectionRule] | 
					
						
							|  |  |  |     location_rules: Dict[str, CollectionRule] | 
					
						
							|  |  |  |     maximum_price: int | 
					
						
							|  |  |  |     required_seals: int | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |     def __init__(self, world: "MessengerWorld") -> None: | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |         self.player = world.player | 
					
						
							|  |  |  |         self.world = world | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |         # these locations are at the top of the shop tree, and the entire shop tree needs to be purchased | 
					
						
							|  |  |  |         maximum_price = (world.multiworld.get_location("The Shop - Demon's Bane", self.player).cost + | 
					
						
							|  |  |  |                          world.multiworld.get_location("The Shop - Focused Power Sense", self.player).cost) | 
					
						
							|  |  |  |         self.maximum_price = min(maximum_price, world.total_shards) | 
					
						
							|  |  |  |         self.required_seals = max(1, world.required_seals) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |         # dict of connection names and requirements to traverse the exit | 
					
						
							|  |  |  |         self.connection_rules = { | 
					
						
							|  |  |  |             # from ToTHQ | 
					
						
							|  |  |  |             "Artificer's Portal": | 
					
						
							|  |  |  |                 lambda state: state.has_all({"Demon King Crown", "Magic Firefly"}, self.player), | 
					
						
							|  |  |  |             "Shrink Down": | 
					
						
							|  |  |  |                 lambda state: state.has_all(NOTES, self.player) or self.has_enough_seals(state), | 
					
						
							|  |  |  |             # the shop | 
					
						
							|  |  |  |             "Money Sink": | 
					
						
							|  |  |  |                 lambda state: state.has("Money Wrench", self.player) and self.can_shop(state), | 
					
						
							|  |  |  |             # Autumn Hills | 
					
						
							|  |  |  |             "Autumn Hills - Portal -> Autumn Hills - Dimension Climb Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and self.has_dart(state), | 
					
						
							|  |  |  |             "Autumn Hills - Dimension Climb Shop -> Autumn Hills - Portal": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Autumn Hills - Climbing Claws Shop -> Autumn Hills - Hope Path Shop": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Autumn Hills - Climbing Claws Shop -> Autumn Hills - Key of Hope Checkpoint": | 
					
						
							|  |  |  |                 self.false,  # hard logic only | 
					
						
							|  |  |  |             "Autumn Hills - Hope Path Shop -> Autumn Hills - Hope Latch Checkpoint": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Autumn Hills - Hope Path Shop -> Autumn Hills - Climbing Claws Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and self.can_dboost(state), | 
					
						
							|  |  |  |             "Autumn Hills - Hope Path Shop -> Autumn Hills - Lakeside Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and self.can_dboost(state), | 
					
						
							|  |  |  |             "Autumn Hills - Hope Latch Checkpoint -> Autumn Hills - Hope Path Shop": | 
					
						
							|  |  |  |                 self.can_dboost, | 
					
						
							|  |  |  |             "Autumn Hills - Hope Latch Checkpoint -> Autumn Hills - Key of Hope Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and self.has_wingsuit(state), | 
					
						
							|  |  |  |             # Forlorn Temple | 
					
						
							|  |  |  |             "Forlorn Temple - Outside Shop -> Forlorn Temple - Entrance Shop": | 
					
						
							|  |  |  |                 lambda state: state.has_all(PHOBEKINS, self.player), | 
					
						
							|  |  |  |             "Forlorn Temple - Entrance Shop -> Forlorn Temple - Outside Shop": | 
					
						
							|  |  |  |                 lambda state: state.has_all(PHOBEKINS, self.player), | 
					
						
							|  |  |  |             "Forlorn Temple - Entrance Shop -> Forlorn Temple - Sunny Day Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_vertical(state) and self.can_dboost(state), | 
					
						
							|  |  |  |             "Forlorn Temple - Sunny Day Checkpoint -> Forlorn Temple - Rocket Maze Checkpoint": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Forlorn Temple - Rocket Sunset Shop -> Forlorn Temple - Descent Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and (self.can_dboost(state) or self.has_wingsuit(state)), | 
					
						
							|  |  |  |             "Forlorn Temple - Saw Gauntlet Shop -> Forlorn Temple - Demon King Shop": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Forlorn Temple - Demon King Shop -> Forlorn Temple - Saw Gauntlet Shop": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             # Howling Grotto | 
					
						
							|  |  |  |             "Howling Grotto - Portal -> Howling Grotto - Crushing Pits Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Howling Grotto - Wingsuit Shop -> Howling Grotto - Left": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Howling Grotto - Wingsuit Shop -> Howling Grotto - Lost Woods Checkpoint": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Howling Grotto - Lost Woods Checkpoint -> Howling Grotto - Bottom": | 
					
						
							|  |  |  |                 lambda state: state.has("Seashell", self.player), | 
					
						
							|  |  |  |             "Howling Grotto - Crushing Pits Shop -> Howling Grotto - Portal": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) or self.can_dboost(state), | 
					
						
							|  |  |  |             "Howling Grotto - Breezy Crushers Checkpoint -> Howling Grotto - Emerald Golem Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Howling Grotto - Breezy Crushers Checkpoint -> Howling Grotto - Crushing Pits Shop": | 
					
						
							|  |  |  |                 lambda state: (self.has_wingsuit(state) or self.can_dboost( | 
					
						
							|  |  |  |                     state | 
					
						
							|  |  |  |                 ) or self.can_destroy_projectiles(state)) | 
					
						
							|  |  |  |                               and state.multiworld.get_region( | 
					
						
							|  |  |  |                     "Howling Grotto - Emerald Golem Shop", self.player | 
					
						
							|  |  |  |                 ).can_reach(state), | 
					
						
							|  |  |  |             "Howling Grotto - Emerald Golem Shop -> Howling Grotto - Right": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             # Searing Crags | 
					
						
							|  |  |  |             "Searing Crags - Rope Dart Shop -> Searing Crags - Triple Ball Spinner Checkpoint": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Searing Crags - Portal -> Searing Crags - Right": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Searing Crags - Portal -> Searing Crags - Before Final Climb Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Searing Crags - Portal -> Searing Crags - Colossuses Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Searing Crags - Bottom -> Searing Crags - Portal": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Searing Crags - Right -> Searing Crags - Portal": | 
					
						
							|  |  |  |                 lambda state: self.has_tabi(state) and self.has_wingsuit(state), | 
					
						
							|  |  |  |             "Searing Crags - Colossuses Shop -> Searing Crags - Key of Strength Shop": | 
					
						
							|  |  |  |                 lambda state: state.has("Power Thistle", self.player) | 
					
						
							|  |  |  |                               and (self.has_dart(state) | 
					
						
							|  |  |  |                                    or (self.has_wingsuit(state) | 
					
						
							|  |  |  |                                        and self.can_destroy_projectiles(state))), | 
					
						
							|  |  |  |             "Searing Crags - Falling Rocks Shop -> Searing Crags - Searing Mega Shard Shop": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Searing Crags - Searing Mega Shard Shop -> Searing Crags - Before Final Climb Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) or self.can_destroy_projectiles(state), | 
					
						
							|  |  |  |             "Searing Crags - Searing Mega Shard Shop -> Searing Crags - Falling Rocks Shop": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Searing Crags - Searing Mega Shard Shop -> Searing Crags - Key of Strength Shop": | 
					
						
							|  |  |  |                 self.false, | 
					
						
							|  |  |  |             "Searing Crags - Before Final Climb Shop -> Searing Crags - Colossuses Shop": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             # Glacial Peak | 
					
						
							|  |  |  |             "Glacial Peak - Portal -> Glacial Peak - Tower Entrance Shop": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Glacial Peak - Left -> Elemental Skylands - Air Shmup": | 
					
						
							|  |  |  |                 lambda state: state.has("Magic Firefly", self.player) | 
					
						
							|  |  |  |                               and state.multiworld.get_location("Quillshroom Marsh - Queen of Quills", self.player) | 
					
						
							|  |  |  |                               .can_reach(state), | 
					
						
							|  |  |  |             "Glacial Peak - Tower Entrance Shop -> Glacial Peak - Top": | 
					
						
							|  |  |  |                 lambda state: state.has("Ruxxtin's Amulet", self.player), | 
					
						
							|  |  |  |             "Glacial Peak - Projectile Spike Pit Checkpoint -> Glacial Peak - Left": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) or (self.can_dboost(state) and self.has_wingsuit(state)), | 
					
						
							|  |  |  |             # Tower of Time | 
					
						
							|  |  |  |             "Tower of Time - Left -> Tower of Time - Final Chance Shop": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Tower of Time - Second Checkpoint -> Tower of Time - Third Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and (self.has_dart(state) or self.can_dboost(state)), | 
					
						
							|  |  |  |             "Tower of Time - Third Checkpoint -> Tower of Time - Fourth Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) or self.can_dboost(state), | 
					
						
							|  |  |  |             "Tower of Time - Fourth Checkpoint -> Tower of Time - Fifth Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and self.has_dart(state), | 
					
						
							|  |  |  |             "Tower of Time - Fifth Checkpoint -> Tower of Time - Sixth Checkpoint": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             # Cloud Ruins | 
					
						
							|  |  |  |             "Cloud Ruins - Cloud Entrance Shop -> Cloud Ruins - Spike Float Checkpoint": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Cloud Ruins - Spike Float Checkpoint -> Cloud Ruins - Cloud Entrance Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_vertical(state) or self.can_dboost(state), | 
					
						
							|  |  |  |             "Cloud Ruins - Spike Float Checkpoint -> Cloud Ruins - Pillar Glide Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_vertical(state) or self.can_dboost(state), | 
					
						
							|  |  |  |             "Cloud Ruins - Pillar Glide Shop -> Cloud Ruins - Spike Float Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_vertical(state) and self.can_double_dboost(state), | 
					
						
							|  |  |  |             "Cloud Ruins - Pillar Glide Shop -> Cloud Ruins - Ghost Pit Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and self.has_wingsuit(state), | 
					
						
							|  |  |  |             "Cloud Ruins - Pillar Glide Shop -> Cloud Ruins - Crushers' Descent Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and (self.has_dart(state) or self.can_dboost(state)), | 
					
						
							|  |  |  |             "Cloud Ruins - Toothbrush Alley Checkpoint -> Cloud Ruins - Seeing Spikes Shop": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Cloud Ruins - Seeing Spikes Shop -> Cloud Ruins - Sliding Spikes Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Cloud Ruins - Sliding Spikes Shop -> Cloud Ruins - Seeing Spikes Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Cloud Ruins - Sliding Spikes Shop -> Cloud Ruins - Saw Pit Checkpoint": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Cloud Ruins - Final Flight Shop -> Cloud Ruins - Manfred's Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and self.has_dart(state), | 
					
						
							|  |  |  |             "Cloud Ruins - Manfred's Shop -> Cloud Ruins - Final Flight Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and self.can_dboost(state), | 
					
						
							|  |  |  |             # Underworld | 
					
						
							|  |  |  |             "Underworld - Left -> Underworld - Left Shop": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Underworld - Left Shop -> Underworld - Left": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Underworld - Hot Dip Checkpoint -> Underworld - Lava Run Checkpoint": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Underworld - Fireball Wave Shop -> Underworld - Long Climb Shop": | 
					
						
							|  |  |  |                 lambda state: self.can_destroy_projectiles(state) or self.has_tabi(state) or self.has_vertical(state), | 
					
						
							|  |  |  |             "Underworld - Long Climb Shop -> Underworld - Hot Tub Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_tabi(state) | 
					
						
							|  |  |  |                               and (self.can_destroy_projectiles(state) | 
					
						
							|  |  |  |                                    or self.has_wingsuit(state)) | 
					
						
							|  |  |  |                               or (self.has_wingsuit(state) | 
					
						
							|  |  |  |                                   and (self.has_dart(state) | 
					
						
							|  |  |  |                                        or self.can_dboost(state) | 
					
						
							|  |  |  |                                        or self.can_destroy_projectiles(state))), | 
					
						
							|  |  |  |             "Underworld - Hot Tub Checkpoint -> Underworld - Long Climb Shop": | 
					
						
							|  |  |  |                 lambda state: self.has_tabi(state) | 
					
						
							|  |  |  |                               or self.can_destroy_projectiles(state) | 
					
						
							|  |  |  |                               or (self.has_dart(state) and self.has_wingsuit(state)), | 
					
						
							|  |  |  |             # Dark Cave | 
					
						
							|  |  |  |             "Dark Cave - Right -> Dark Cave - Left": | 
					
						
							|  |  |  |                 lambda state: state.has("Candle", self.player) and self.has_dart(state), | 
					
						
							|  |  |  |             # Riviere Turquoise | 
					
						
							|  |  |  |             "Riviere Turquoise - Waterfall Shop -> Riviere Turquoise - Flower Flight Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) or ( | 
					
						
							|  |  |  |                             self.has_wingsuit(state) and self.can_destroy_projectiles(state)), | 
					
						
							|  |  |  |             "Riviere Turquoise - Launch of Faith Shop -> Riviere Turquoise - Flower Flight Checkpoint": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and self.can_dboost(state), | 
					
						
							|  |  |  |             "Riviere Turquoise - Flower Flight Checkpoint -> Riviere Turquoise - Waterfall Shop": | 
					
						
							|  |  |  |                 lambda state: False, | 
					
						
							|  |  |  |             # Elemental Skylands | 
					
						
							|  |  |  |             "Elemental Skylands - Air Intro Shop -> Elemental Skylands - Air Seal Checkpoint": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Elemental Skylands - Air Intro Shop -> Elemental Skylands - Air Generator Shop": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             # Sunken Shrine | 
					
						
							|  |  |  |             "Sunken Shrine - Portal -> Sunken Shrine - Sun Path Shop": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Sunken Shrine - Portal -> Sunken Shrine - Moon Path Shop": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Sunken Shrine - Moon Path Shop -> Sunken Shrine - Waterfall Paradise Checkpoint": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Sunken Shrine - Waterfall Paradise Checkpoint -> Sunken Shrine - Moon Path Shop": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Sunken Shrine - Tabi Gauntlet Shop -> Sunken Shrine - Sun Path Shop": | 
					
						
							|  |  |  |                 lambda state: self.can_dboost(state) or self.has_dart(state), | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |         self.location_rules = { | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # ninja village | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Ninja Village Seal - Tree House": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Ninja Village - Candle": | 
					
						
							|  |  |  |                 lambda state: state.multiworld.get_location("Searing Crags - Astral Tea Leaves", self.player).can_reach( | 
					
						
							|  |  |  |                     state), | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # autumn hills | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Autumn Hills Seal - Spike Ball Darts": | 
					
						
							|  |  |  |                 self.is_aerobatic, | 
					
						
							|  |  |  |             "Autumn Hills Seal - Trip Saws": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							| 
									
										
										
										
											2024-06-19 09:20:47 -05:00
										 |  |  |             "Autumn Hills Seal - Double Swing Saws": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             # forlorn temple | 
					
						
							|  |  |  |             "Forlorn Temple Seal - Rocket Maze": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |             # bamboo creek | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Bamboo Creek - Claustro": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and (self.has_dart(state) or self.can_dboost(state)), | 
					
						
							|  |  |  |             "Above Entrance Mega Shard": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) or self.can_dboost(state), | 
					
						
							|  |  |  |             "Bamboo Creek Seal - Spike Ball Pits": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # howling grotto | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Howling Grotto Seal - Windy Saws and Balls": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Howling Grotto Seal - Crushing Pits": | 
					
						
							|  |  |  |                 lambda state: self.has_wingsuit(state) and self.has_dart(state), | 
					
						
							|  |  |  |             "Howling Grotto - Emerald Golem": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # searing crags | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |             "Searing Crags - Astral Tea Leaves": | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |                 lambda state: state.multiworld.get_location("Ninja Village - Astral Seed", self.player).can_reach(state), | 
					
						
							|  |  |  |             "Searing Crags Seal - Triple Ball Spinner": | 
					
						
							|  |  |  |                 self.can_dboost, | 
					
						
							|  |  |  |             "Searing Crags - Pyro": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # glacial peak | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Glacial Peak Seal - Ice Climbers": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Glacial Peak Seal - Projectile Spike Pit": | 
					
						
							|  |  |  |                 self.can_destroy_projectiles, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # tower of time | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Tower of Time Seal - Time Waster": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             # cloud ruins | 
					
						
							|  |  |  |             "Time Warp Mega Shard": | 
					
						
							|  |  |  |                 lambda state: self.has_vertical(state) or self.can_dboost(state), | 
					
						
							|  |  |  |             "Cloud Ruins Seal - Ghost Pit": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							|  |  |  |             "Cloud Ruins Seal - Toothbrush Alley": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Cloud Ruins Seal - Saw Pit": | 
					
						
							|  |  |  |                 self.has_vertical, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # underworld | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Underworld Seal - Sharp and Windy Climb": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Underworld Seal - Fireball Wave": | 
					
						
							|  |  |  |                 self.is_aerobatic, | 
					
						
							|  |  |  |             "Underworld Seal - Rising Fanta": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Hot Tub Mega Shard": | 
					
						
							|  |  |  |                 lambda state: self.has_tabi(state) or self.has_dart(state), | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # sunken shrine | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Sunken Shrine - Key of Love": | 
					
						
							|  |  |  |                 lambda state: state.has_all({"Sun Crest", "Moon Crest"}, self.player), | 
					
						
							|  |  |  |             "Sunken Shrine Seal - Waterfall Paradise": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Sunken Shrine Seal - Tabi Gauntlet": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							|  |  |  |             "Mega Shard of the Sun": | 
					
						
							|  |  |  |                 self.has_tabi, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # riviere turquoise | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Riviere Turquoise Seal - Bounces and Balls": | 
					
						
							|  |  |  |                 self.can_dboost, | 
					
						
							|  |  |  |             "Riviere Turquoise Seal - Launch of Faith": | 
					
						
							|  |  |  |                 lambda state: self.has_vertical(state), | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |             # elemental skylands | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Elemental Skylands - Key of Symbiosis": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Elemental Skylands Seal - Air": | 
					
						
							|  |  |  |                 self.has_wingsuit, | 
					
						
							|  |  |  |             "Elemental Skylands Seal - Water": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and state.has("Currents Master", self.player), | 
					
						
							|  |  |  |             "Elemental Skylands Seal - Fire": | 
					
						
							|  |  |  |                 lambda state: self.has_dart(state) and self.can_destroy_projectiles(state) and self.is_aerobatic(state), | 
					
						
							|  |  |  |             "Earth Mega Shard": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							|  |  |  |             "Water Mega Shard": | 
					
						
							|  |  |  |                 self.has_dart, | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_wingsuit(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has("Wingsuit", self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_dart(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has("Rope Dart", self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_tabi(self, state: CollectionState) -> bool: | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |         return state.has("Lightfoot Tabi", self.player) | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_vertical(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return self.has_wingsuit(state) or self.has_dart(state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_enough_seals(self, state: CollectionState) -> bool: | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |         return state.has("Power Seal", self.player, self.required_seals) | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |     def can_destroy_projectiles(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has("Strike of the Ninja", self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_dboost(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has_any({"Path of Resilience", "Meditation"}, self.player) and \ | 
					
						
							|  |  |  |             state.has("Second Wind", self.player) | 
					
						
							| 
									
										
										
										
											2023-10-08 07:33:39 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     def can_double_dboost(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has_all({"Path of Resilience", "Meditation", "Second Wind"}, self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |     def is_aerobatic(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return self.has_wingsuit(state) and state.has("Aerobatics Warrior", self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |     def true(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         """I know this is stupid, but it's easier to read in the dicts.""" | 
					
						
							|  |  |  |         return True | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     def false(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         """It's a bit easier to just always create the connections that are only possible in hard or higher logic.""" | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |     def can_shop(self, state: CollectionState) -> bool: | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |         return state.has("Shards", self.player, self.maximum_price) | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  |     def set_messenger_rules(self) -> None: | 
					
						
							|  |  |  |         multiworld = self.world.multiworld | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |         for entrance_name, rule in self.connection_rules.items(): | 
					
						
							|  |  |  |             entrance = multiworld.get_entrance(entrance_name, self.player) | 
					
						
							|  |  |  |             entrance.access_rule = rule | 
					
						
							|  |  |  |         for loc in multiworld.get_locations(self.player): | 
					
						
							|  |  |  |             if loc.name in self.location_rules: | 
					
						
							|  |  |  |                 loc.access_rule = self.location_rules[loc.name] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.world.options.music_box and not self.world.options.limited_movement: | 
					
						
							|  |  |  |             add_rule(multiworld.get_entrance("Shrink Down", self.player), self.has_dart) | 
					
						
							|  |  |  |         multiworld.completion_condition[self.player] = lambda state: state.has("Do the Thing!", self.player) | 
					
						
							|  |  |  |         if self.world.options.accessibility:  # not locations accessibility | 
					
						
							| 
									
										
										
										
											2023-10-10 15:30:20 -05:00
										 |  |  |             set_self_locking_items(self.world, self.player) | 
					
						
							| 
									
										
										
										
											2023-03-12 09:05:50 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  | class MessengerHardRules(MessengerRules): | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |     def __init__(self, world: "MessengerWorld") -> None: | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |         super().__init__(world) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |         self.connection_rules.update( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 # Autumn Hills | 
					
						
							|  |  |  |                 "Autumn Hills - Portal -> Autumn Hills - Dimension Climb Shop": | 
					
						
							|  |  |  |                     self.has_dart, | 
					
						
							|  |  |  |                 "Autumn Hills - Climbing Claws Shop -> Autumn Hills - Key of Hope Checkpoint": | 
					
						
							|  |  |  |                     self.true,  # super easy normal clip - also possible with moderately difficult cloud stepping | 
					
						
							|  |  |  |                 # Howling Grotto | 
					
						
							|  |  |  |                 "Howling Grotto - Portal -> Howling Grotto - Crushing Pits Shop": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Howling Grotto - Lost Woods Checkpoint -> Howling Grotto - Bottom": | 
					
						
							|  |  |  |                     self.true,  # just memorize the pattern :) | 
					
						
							|  |  |  |                 "Howling Grotto - Crushing Pits Shop -> Howling Grotto - Portal": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Howling Grotto - Breezy Crushers Checkpoint -> Howling Grotto - Emerald Golem Shop": | 
					
						
							|  |  |  |                     lambda state: self.has_wingsuit(state) or  # there's a very easy normal clip here but it's 16-bit only | 
					
						
							|  |  |  |                                   "Howling Grotto - Breezy Crushers Checkpoint" in self.world.spoiler_portal_mapping.values(), | 
					
						
							|  |  |  |                 # Searing Crags | 
					
						
							|  |  |  |                 "Searing Crags - Rope Dart Shop -> Searing Crags - Triple Ball Spinner Checkpoint": | 
					
						
							|  |  |  |                     lambda state: self.has_vertical(state) or self.can_destroy_projectiles(state), | 
					
						
							|  |  |  |                 # it's doable without anything but one jump is pretty hard and time warping is no longer reliable | 
					
						
							|  |  |  |                 "Searing Crags - Falling Rocks Shop -> Searing Crags - Searing Mega Shard Shop": | 
					
						
							|  |  |  |                     lambda state: self.has_vertical(state) or self.can_destroy_projectiles(state), | 
					
						
							|  |  |  |                 "Searing Crags - Searing Mega Shard Shop -> Searing Crags - Falling Rocks Shop": | 
					
						
							|  |  |  |                     lambda state: self.has_dart(state) or | 
					
						
							|  |  |  |                                   (self.can_destroy_projectiles(state) and | 
					
						
							|  |  |  |                                    (self.has_wingsuit(state) or self.can_dboost(state))), | 
					
						
							|  |  |  |                 "Searing Crags - Searing Mega Shard Shop -> Searing Crags - Key of Strength Shop": | 
					
						
							|  |  |  |                     lambda state: self.can_leash(state) or self.has_windmill(state), | 
					
						
							|  |  |  |                 "Searing Crags - Before Final Climb Shop -> Searing Crags - Colossuses Shop": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 # Glacial Peak | 
					
						
							|  |  |  |                 "Glacial Peak - Left -> Elemental Skylands - Air Shmup": | 
					
						
							|  |  |  |                     lambda state: self.has_windmill(state) or | 
					
						
							|  |  |  |                                   (state.has("Magic Firefly", self.player) and | 
					
						
							|  |  |  |                                    state.multiworld.get_location( | 
					
						
							|  |  |  |                                        "Quillshroom Marsh - Queen of Quills", self.player).can_reach(state)) or | 
					
						
							|  |  |  |                                   (self.has_dart(state) and self.can_dboost(state)), | 
					
						
							|  |  |  |                 "Glacial Peak - Projectile Spike Pit Checkpoint -> Glacial Peak - Left": | 
					
						
							|  |  |  |                     lambda state: self.has_vertical(state) or self.has_windmill(state), | 
					
						
							|  |  |  |                 # Cloud Ruins | 
					
						
							|  |  |  |                 "Cloud Ruins - Sliding Spikes Shop -> Cloud Ruins - Saw Pit Checkpoint": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 # Elemental Skylands | 
					
						
							|  |  |  |                 "Elemental Skylands - Air Intro Shop -> Elemental Skylands - Air Generator Shop": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 # Riviere Turquoise | 
					
						
							|  |  |  |                 "Riviere Turquoise - Waterfall Shop -> Riviere Turquoise - Flower Flight Checkpoint": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Riviere Turquoise - Launch of Faith Shop -> Riviere Turquoise - Flower Flight Checkpoint": | 
					
						
							|  |  |  |                     self.can_dboost, | 
					
						
							|  |  |  |                 "Riviere Turquoise - Flower Flight Checkpoint -> Riviere Turquoise - Waterfall Shop": | 
					
						
							|  |  |  |                     self.can_double_dboost, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.location_rules.update( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Autumn Hills Seal - Spike Ball Darts": | 
					
						
							|  |  |  |                     lambda state: self.has_vertical(state) and self.has_windmill(state) or self.is_aerobatic(state), | 
					
						
							| 
									
										
										
										
											2024-06-19 09:20:47 -05:00
										 |  |  |                 "Autumn Hills Seal - Double Swing Saws": | 
					
						
							|  |  |  |                     lambda state: self.has_vertical(state) or self.can_destroy_projectiles(state), | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |                 "Bamboo Creek - Claustro": | 
					
						
							|  |  |  |                     self.has_wingsuit, | 
					
						
							|  |  |  |                 "Bamboo Creek Seal - Spike Ball Pits": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Howling Grotto Seal - Windy Saws and Balls": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Searing Crags Seal - Triple Ball Spinner": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Glacial Peak Seal - Ice Climbers": | 
					
						
							|  |  |  |                     lambda state: self.has_vertical(state) or self.can_dboost(state), | 
					
						
							|  |  |  |                 "Glacial Peak Seal - Projectile Spike Pit": | 
					
						
							|  |  |  |                     lambda state: self.can_dboost(state) or self.can_destroy_projectiles(state), | 
					
						
							|  |  |  |                 "Glacial Peak Seal - Glacial Air Swag": | 
					
						
							|  |  |  |                     lambda state: self.has_windmill(state) or self.has_vertical(state), | 
					
						
							|  |  |  |                 "Glacial Peak Mega Shard": | 
					
						
							|  |  |  |                     lambda state: self.has_windmill(state) or self.has_vertical(state), | 
					
						
							|  |  |  |                 "Cloud Ruins Seal - Ghost Pit": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Cloud Ruins Seal - Toothbrush Alley": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Cloud Ruins Seal - Saw Pit": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Underworld Seal - Fireball Wave": | 
					
						
							|  |  |  |                     lambda state: self.is_aerobatic(state) or self.has_windmill(state), | 
					
						
							|  |  |  |                 "Riviere Turquoise Seal - Bounces and Balls": | 
					
						
							|  |  |  |                     self.true, | 
					
						
							|  |  |  |                 "Riviere Turquoise Seal - Launch of Faith": | 
					
						
							|  |  |  |                     lambda state: self.can_dboost(state) or self.has_vertical(state), | 
					
						
							|  |  |  |                 "Elemental Skylands - Key of Symbiosis": | 
					
						
							|  |  |  |                     lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state), | 
					
						
							|  |  |  |                 "Elemental Skylands Seal - Water": | 
					
						
							|  |  |  |                     lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state), | 
					
						
							|  |  |  |                 "Elemental Skylands Seal - Fire": | 
					
						
							|  |  |  |                     lambda state: (self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state)) | 
					
						
							|  |  |  |                                   and self.can_destroy_projectiles(state), | 
					
						
							|  |  |  |                 "Earth Mega Shard": | 
					
						
							|  |  |  |                     lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state), | 
					
						
							|  |  |  |                 "Water Mega Shard": | 
					
						
							|  |  |  |                     lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state), | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_windmill(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has("Windmill Shuriken", self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     def can_dboost(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return state.has("Second Wind", self.player)  # who really needs meditation | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def can_destroy_projectiles(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return super().can_destroy_projectiles(state) or self.has_windmill(state) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_leash(self, state: CollectionState) -> bool: | 
					
						
							|  |  |  |         return self.has_dart(state) and self.can_dboost(state) | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MessengerOOBRules(MessengerRules): | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |     def __init__(self, world: "MessengerWorld") -> None: | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |         self.world = world | 
					
						
							|  |  |  |         self.player = world.player | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |         self.required_seals = max(1, world.required_seals) | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |         self.region_rules = { | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |             "Elemental Skylands": | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |                 lambda state: state.has_any( | 
					
						
							|  |  |  |                     {"Windmill Shuriken", "Wingsuit", "Rope Dart", "Magic Firefly"}, self.player | 
					
						
							|  |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  |             "Music Box": lambda state: state.has_all(set(NOTES), self.player) or self.has_enough_seals(state), | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.location_rules = { | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |             "Bamboo Creek - Claustro": self.has_wingsuit, | 
					
						
							|  |  |  |             "Searing Crags - Key of Strength": self.has_wingsuit, | 
					
						
							|  |  |  |             "Sunken Shrine - Key of Love": lambda state: state.has_all({"Sun Crest", "Moon Crest"}, self.player), | 
					
						
							|  |  |  |             "Searing Crags - Pyro": self.has_tabi, | 
					
						
							|  |  |  |             "Underworld - Key of Chaos": self.has_tabi, | 
					
						
							|  |  |  |             "Corrupted Future - Key of Courage": | 
					
						
							|  |  |  |                 lambda state: state.has_all({"Demon King Crown", "Magic Firefly"}, self.player), | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |             "Autumn Hills Seal - Spike Ball Darts": self.has_dart, | 
					
						
							|  |  |  |             "Ninja Village Seal - Tree House": self.has_dart, | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |             "Underworld Seal - Fireball Wave": lambda state: state.has_any( | 
					
						
							|  |  |  |                 {"Wingsuit", "Windmill Shuriken"}, | 
					
						
							|  |  |  |                 self.player | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2023-06-27 18:39:52 -05:00
										 |  |  |             "Tower of Time Seal - Time Waster": self.has_dart, | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_messenger_rules(self) -> None: | 
					
						
							|  |  |  |         super().set_messenger_rules() | 
					
						
							| 
									
										
										
										
											2023-10-10 15:30:20 -05:00
										 |  |  |         self.world.options.accessibility.value = MessengerAccessibility.option_minimal | 
					
						
							| 
									
										
										
										
											2023-03-21 15:21:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 17:38:57 -06:00
										 |  |  | def set_self_locking_items(world: "MessengerWorld", player: int) -> None: | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     # locations where these placements are always valid | 
					
						
							| 
									
										
										
										
											2024-03-11 18:55:28 -05:00
										 |  |  |     allow_self_locking_items(world.get_location("Searing Crags - Key of Strength").parent_region, "Power Thistle") | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     allow_self_locking_items(world.get_location("Sunken Shrine - Key of Love"), "Sun Crest", "Moon Crest") | 
					
						
							| 
									
										
										
										
											2024-03-11 18:55:28 -05:00
										 |  |  |     allow_self_locking_items(world.get_location("Corrupted Future - Key of Courage").parent_region, "Demon King Crown") | 
					
						
							| 
									
										
										
										
											2024-03-11 17:23:41 -05:00
										 |  |  |     allow_self_locking_items(world.get_location("Elemental Skylands Seal - Water"), "Currents Master") |