| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | from collections import Counter | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from . import SVTestBase | 
					
						
							|  |  |  | from .. import options | 
					
						
							| 
									
										
										
										
											2023-08-16 10:18:50 -04:00
										 |  |  | from ..locations import locations_by_tag, LocationTags, location_table | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  | from ..strings.animal_names import Animal | 
					
						
							|  |  |  | from ..strings.animal_product_names import AnimalProduct | 
					
						
							|  |  |  | from ..strings.artisan_good_names import ArtisanGood | 
					
						
							|  |  |  | from ..strings.crop_names import Vegetable | 
					
						
							| 
									
										
										
										
											2023-08-16 10:18:50 -04:00
										 |  |  | from ..strings.entrance_names import Entrance | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  | from ..strings.food_names import Meal | 
					
						
							|  |  |  | from ..strings.ingredient_names import Ingredient | 
					
						
							|  |  |  | from ..strings.machine_names import Machine | 
					
						
							|  |  |  | from ..strings.region_names import Region | 
					
						
							|  |  |  | from ..strings.season_names import Season | 
					
						
							|  |  |  | from ..strings.seed_names import Seed | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestProgressiveToolsLogic(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.ToolProgression.internal_name: options.ToolProgression.option_progressive, | 
					
						
							|  |  |  |         options.SeasonRandomization.internal_name: options.SeasonRandomization.option_randomized, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         super().setUp() | 
					
						
							|  |  |  |         self.multiworld.state.prog_items = Counter() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_sturgeon(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         summer = self.world.create_item("Summer") | 
					
						
							|  |  |  |         self.multiworld.state.collect(summer, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         fishing_rod = self.world.create_item("Progressive Fishing Rod") | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_rod, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_rod, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         fishing_level = self.world.create_item("Fishing Level") | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_level, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_level, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_level, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_level, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_level, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(fishing_level, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.remove(summer) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         winter = self.world.create_item("Winter") | 
					
						
							|  |  |  |         self.multiworld.state.collect(winter, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.remove(fishing_rod) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.has("Sturgeon")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_old_master_cannoli(self): | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Axe"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Axe"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Summer"), event=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         fall = self.world.create_item("Fall") | 
					
						
							|  |  |  |         self.multiworld.state.collect(fall, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         tuesday = self.world.create_item("Traveling Merchant: Tuesday") | 
					
						
							|  |  |  |         self.multiworld.state.collect(tuesday, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rare_seed = self.world.create_item("Rare Seed") | 
					
						
							|  |  |  |         self.multiworld.state.collect(rare_seed, event=True) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.remove(fall) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(tuesday) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         green_house = self.world.create_item("Greenhouse") | 
					
						
							|  |  |  |         self.multiworld.state.collect(green_house, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         friday = self.world.create_item("Traveling Merchant: Friday") | 
					
						
							|  |  |  |         self.multiworld.state.collect(friday, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.multiworld.get_location("Old Master Cannoli", 1).access_rule(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.remove(green_house) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Old Master Cannoli")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(friday) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestBundlesLogic(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_vault_2500g_bundle(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_location("2,500g Bundle")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestBuildingLogic(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.BuildingProgression.internal_name: options.BuildingProgression.option_progressive_early_shipping_bin | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_coop_blueprint(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Coop Blueprint")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_location("Coop Blueprint")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_big_coop_blueprint(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Big Coop Blueprint")(self.multiworld.state), | 
					
						
							|  |  |  |             f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}") | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Big Coop Blueprint")(self.multiworld.state), | 
					
						
							|  |  |  |             f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}") | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Coop"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_location("Big Coop Blueprint")(self.multiworld.state), | 
					
						
							|  |  |  |             f"Rule is {repr(self.multiworld.get_location('Big Coop Blueprint', self.player).access_rule)}") | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_deluxe_coop_blueprint(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Coop"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Coop"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_location("Deluxe Coop Blueprint")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_big_shed_blueprint(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Big Shed Blueprint")(self.multiworld.state), | 
					
						
							|  |  |  |             f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}") | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Month End"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_location("Big Shed Blueprint")(self.multiworld.state), | 
					
						
							|  |  |  |             f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}") | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Shed"), event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_location("Big Shed Blueprint")(self.multiworld.state), | 
					
						
							|  |  |  |             f"Rule is {repr(self.multiworld.get_location('Big Shed Blueprint', self.player).access_rule)}") | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestArcadeMachinesLogic(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.ArcadeMachineLocations.internal_name: options.ArcadeMachineLocations.option_full_shuffling, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_prairie_king(self): | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 1")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 2")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 3")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_location("Journey of the Prairie King Victory")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         boots = self.world.create_item("JotPK: Progressive Boots") | 
					
						
							|  |  |  |         gun = self.world.create_item("JotPK: Progressive Gun") | 
					
						
							|  |  |  |         ammo = self.world.create_item("JotPK: Progressive Ammo") | 
					
						
							|  |  |  |         life = self.world.create_item("JotPK: Extra Life") | 
					
						
							|  |  |  |         drop = self.world.create_item("JotPK: Increased Drop Rate") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 1")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 2")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 3")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_location("Journey of the Prairie King Victory")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(boots) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 1")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 2")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 3")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_location("Journey of the Prairie King Victory")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(boots) | 
					
						
							|  |  |  |         self.remove(boots) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(ammo, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(life, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 1")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 2")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_region("JotPK World 3")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_location("Journey of the Prairie King Victory")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(boots) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(ammo) | 
					
						
							|  |  |  |         self.remove(life) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(ammo, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(ammo, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(life, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(drop, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 1")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 2")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 3")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertFalse(self.world.logic.can_reach_location("Journey of the Prairie King Victory")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(boots) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(ammo) | 
					
						
							|  |  |  |         self.remove(ammo) | 
					
						
							|  |  |  |         self.remove(life) | 
					
						
							|  |  |  |         self.remove(drop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(boots, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(gun, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(ammo, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(ammo, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(ammo, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(life, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(drop, event=True) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 1")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 2")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_region("JotPK World 3")(self.multiworld.state)) | 
					
						
							|  |  |  |         self.assertTrue(self.world.logic.can_reach_location("Journey of the Prairie King Victory")(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.remove(boots) | 
					
						
							|  |  |  |         self.remove(boots) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(gun) | 
					
						
							|  |  |  |         self.remove(ammo) | 
					
						
							|  |  |  |         self.remove(ammo) | 
					
						
							|  |  |  |         self.remove(ammo) | 
					
						
							|  |  |  |         self.remove(life) | 
					
						
							|  |  |  |         self.remove(drop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestWeaponsLogic(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.ToolProgression.internal_name: options.ToolProgression.option_progressive, | 
					
						
							|  |  |  |         options.SkillProgression.internal_name: options.SkillProgression.option_progressive, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_mine(self): | 
					
						
							|  |  |  |         self.collect(self.world.create_item("Adventurer's Guild")) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Pickaxe"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Pickaxe"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Pickaxe"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive Pickaxe"), event=True) | 
					
						
							|  |  |  |         self.collect([self.world.create_item("Combat Level")] * 10) | 
					
						
							|  |  |  |         self.collect([self.world.create_item("Progressive Mine Elevator")] * 24) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Bus Repair"), event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Skull Key"), event=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Rusty Sword", 1) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Wooden Blade", 1) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Elf Blade", 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Silver Saber", 2) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Crystal Dagger", 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Claymore", 3) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Obsidian Edge", 3) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Bone Sword", 3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("The Slammer", 4) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Lava Katana", 4) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Galaxy Sword", 5) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Galaxy Hammer", 5) | 
					
						
							|  |  |  |         self.GiveItemAndCheckReachableMine("Galaxy Dagger", 5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def GiveItemAndCheckReachableMine(self, item_name: str, reachable_level: int): | 
					
						
							|  |  |  |         item = self.multiworld.create_item(item_name, self.player) | 
					
						
							|  |  |  |         self.multiworld.state.collect(item, event=True) | 
					
						
							|  |  |  |         if reachable_level > 0: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertTrue(self.world.logic.can_mine_in_the_mines_floor_1_40()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertFalse(self.world.logic.can_mine_in_the_mines_floor_1_40()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if reachable_level > 1: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertTrue(self.world.logic.can_mine_in_the_mines_floor_41_80()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertFalse(self.world.logic.can_mine_in_the_mines_floor_41_80()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if reachable_level > 2: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertTrue(self.world.logic.can_mine_in_the_mines_floor_81_120()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertFalse(self.world.logic.can_mine_in_the_mines_floor_81_120()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if reachable_level > 3: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertTrue(self.world.logic.can_mine_in_the_skull_cavern()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertFalse(self.world.logic.can_mine_in_the_skull_cavern()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if reachable_level > 4: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertTrue(self.world.logic.can_mine_perfectly_in_the_skull_cavern()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  |             self.assertFalse(self.world.logic.can_mine_perfectly_in_the_skull_cavern()(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.remove(item) | 
					
						
							| 
									
										
										
										
											2023-07-19 14:26:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestRecipeLogic(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.BuildingProgression.internal_name: options.BuildingProgression.option_progressive, | 
					
						
							|  |  |  |         options.SkillProgression.internal_name: options.SkillProgression.option_progressive, | 
					
						
							|  |  |  |         options.Cropsanity.internal_name: options.Cropsanity.option_shuffled, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # I wanted to make a test for different ways to obtain a pizza, but I'm stuck not knowing how to block the immediate purchase from Gus | 
					
						
							|  |  |  |     # def test_pizza(self): | 
					
						
							|  |  |  |     #     world = self.world | 
					
						
							|  |  |  |     #     logic = world.logic | 
					
						
							|  |  |  |     #     multiworld = self.multiworld | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(Ingredient.wheat_flour)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.can_spend_money_at(Region.saloon, 150)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Meal.pizza)(multiworld.state)) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #     self.assertFalse(logic.can_cook()(multiworld.state)) | 
					
						
							|  |  |  |     #     self.collect(world.create_item("Progressive House")) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.can_cook()(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Meal.pizza)(multiworld.state)) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Seed.tomato)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.collect(world.create_item(Seed.tomato)) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(Seed.tomato)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Meal.pizza)(multiworld.state)) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Vegetable.tomato)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.collect(world.create_item(Season.summer)) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(Vegetable.tomato)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Meal.pizza)(multiworld.state)) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Animal.cow)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(AnimalProduct.cow_milk)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.collect(world.create_item("Progressive Barn")) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(Animal.cow)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(AnimalProduct.cow_milk)(multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Meal.pizza)(multiworld.state)) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(Machine.cheese_press)(self.multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertFalse(logic.has(ArtisanGood.cheese)(self.multiworld.state)) | 
					
						
							|  |  |  |     #     self.collect(world.create_item(item) for item in ["Farming Level"] * 6) | 
					
						
							|  |  |  |     #     self.collect(world.create_item(item) for item in ["Progressive Axe"] * 2) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(Machine.cheese_press)(self.multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(ArtisanGood.cheese)(self.multiworld.state)) | 
					
						
							|  |  |  |     #     self.assertTrue(logic.has(Meal.pizza)(self.multiworld.state)) | 
					
						
							| 
									
										
										
										
											2023-08-16 10:18:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestDonationLogicAll(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.Museumsanity.internal_name: options.Museumsanity.option_all | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_make_any_donation_without_museum_access(self): | 
					
						
							|  |  |  |         guild_item = "Adventurer's Guild" | 
					
						
							|  |  |  |         swap_museum_and_guild(self.multiworld, self.player) | 
					
						
							|  |  |  |         collect_all_except(self.multiworld, guild_item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for donation in locations_by_tag[LocationTags.MUSEUM_DONATIONS]: | 
					
						
							|  |  |  |             self.assertFalse(self.world.logic.can_reach_location(donation.name)(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(guild_item), event=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for donation in locations_by_tag[LocationTags.MUSEUM_DONATIONS]: | 
					
						
							|  |  |  |             self.assertTrue(self.world.logic.can_reach_location(donation.name)(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestDonationLogicRandomized(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.Museumsanity.internal_name: options.Museumsanity.option_randomized | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_make_any_donation_without_museum_access(self): | 
					
						
							|  |  |  |         guild_item = "Adventurer's Guild" | 
					
						
							|  |  |  |         swap_museum_and_guild(self.multiworld, self.player) | 
					
						
							|  |  |  |         collect_all_except(self.multiworld, guild_item) | 
					
						
							|  |  |  |         donation_locations = [location for location in self.multiworld.get_locations() if not location.event and LocationTags.MUSEUM_DONATIONS in location_table[location.name].tags] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for donation in donation_locations: | 
					
						
							|  |  |  |             self.assertFalse(self.world.logic.can_reach_location(donation.name)(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(guild_item), event=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for donation in donation_locations: | 
					
						
							|  |  |  |             self.assertTrue(self.world.logic.can_reach_location(donation.name)(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestDonationLogicMilestones(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.Museumsanity.internal_name: options.Museumsanity.option_milestones | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_make_any_donation_without_museum_access(self): | 
					
						
							|  |  |  |         guild_item = "Adventurer's Guild" | 
					
						
							|  |  |  |         swap_museum_and_guild(self.multiworld, self.player) | 
					
						
							|  |  |  |         collect_all_except(self.multiworld, guild_item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for donation in locations_by_tag[LocationTags.MUSEUM_MILESTONES]: | 
					
						
							|  |  |  |             self.assertFalse(self.world.logic.can_reach_location(donation.name)(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(guild_item), event=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for donation in locations_by_tag[LocationTags.MUSEUM_MILESTONES]: | 
					
						
							|  |  |  |             self.assertTrue(self.world.logic.can_reach_location(donation.name)(self.multiworld.state)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def swap_museum_and_guild(multiworld, player): | 
					
						
							|  |  |  |     museum_region = multiworld.get_region(Region.museum, player) | 
					
						
							|  |  |  |     guild_region = multiworld.get_region(Region.adventurer_guild, player) | 
					
						
							|  |  |  |     museum_entrance = multiworld.get_entrance(Entrance.town_to_museum, player) | 
					
						
							|  |  |  |     guild_entrance = multiworld.get_entrance(Entrance.mountain_to_adventurer_guild, player) | 
					
						
							|  |  |  |     museum_entrance.connect(guild_region) | 
					
						
							|  |  |  |     guild_entrance.connect(museum_region) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def collect_all_except(multiworld, item_to_not_collect: str): | 
					
						
							|  |  |  |     for item in multiworld.get_items(): | 
					
						
							|  |  |  |         if item.name != item_to_not_collect: | 
					
						
							|  |  |  |             multiworld.state.collect(item) | 
					
						
							| 
									
										
										
										
											2023-09-14 17:56:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestFriendsanityDatingRules(SVTestBase): | 
					
						
							|  |  |  |     options = { | 
					
						
							|  |  |  |         options.SeasonRandomization.internal_name: options.SeasonRandomization.option_randomized_not_winter, | 
					
						
							|  |  |  |         options.Friendsanity.internal_name: options.Friendsanity.option_all_with_marriage, | 
					
						
							|  |  |  |         options.FriendsanityHeartSize.internal_name: 3 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_earning_dating_heart_requires_dating(self): | 
					
						
							|  |  |  |         month_name = "Month End" | 
					
						
							|  |  |  |         for i in range(12): | 
					
						
							|  |  |  |             month_item = self.world.create_item(month_name) | 
					
						
							|  |  |  |             self.multiworld.state.collect(month_item, event=True) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Beach Bridge"), event=False) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Progressive House"), event=False) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Adventurer's Guild"), event=False) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item("Galaxy Hammer"), event=False) | 
					
						
							|  |  |  |         for i in range(3): | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Progressive Pickaxe"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Progressive Axe"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Progressive Barn"), event=False) | 
					
						
							|  |  |  |         for i in range(10): | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Foraging Level"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Farming Level"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Mining Level"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Combat Level"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Progressive Mine Elevator"), event=False) | 
					
						
							|  |  |  |             self.multiworld.state.collect(self.world.create_item("Progressive Mine Elevator"), event=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         npc = "Abigail" | 
					
						
							|  |  |  |         heart_name = f"{npc} <3" | 
					
						
							|  |  |  |         step = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assert_can_reach_heart_up_to(npc, 3, step) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(heart_name), event=False) | 
					
						
							|  |  |  |         self.assert_can_reach_heart_up_to(npc, 6, step) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(heart_name), event=False) | 
					
						
							|  |  |  |         self.assert_can_reach_heart_up_to(npc, 8, step) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(heart_name), event=False) | 
					
						
							|  |  |  |         self.assert_can_reach_heart_up_to(npc, 10, step) | 
					
						
							|  |  |  |         self.multiworld.state.collect(self.world.create_item(heart_name), event=False) | 
					
						
							|  |  |  |         self.assert_can_reach_heart_up_to(npc, 14, step) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assert_can_reach_heart_up_to(self, npc: str, max_reachable: int, step: int): | 
					
						
							|  |  |  |         prefix = "Friendsanity: " | 
					
						
							|  |  |  |         suffix = " <3" | 
					
						
							|  |  |  |         for i in range(1, max_reachable + 1): | 
					
						
							|  |  |  |             if i % step != 0 and i != 14: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             location = f"{prefix}{npc} {i}{suffix}" | 
					
						
							|  |  |  |             can_reach = self.world.logic.can_reach_location(location)(self.multiworld.state) | 
					
						
							|  |  |  |             self.assertTrue(can_reach, f"Should be able to earn relationship up to {i} hearts") | 
					
						
							|  |  |  |         for i in range(max_reachable + 1, 14 + 1): | 
					
						
							|  |  |  |             if i % step != 0 and i != 14: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             location = f"{prefix}{npc} {i}{suffix}" | 
					
						
							|  |  |  |             can_reach = self.world.logic.can_reach_location(location)(self.multiworld.state) | 
					
						
							|  |  |  |             self.assertFalse(can_reach, f"Should not be able to earn relationship up to {i} hearts") | 
					
						
							|  |  |  | 
 |