| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | from __future__ import annotations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from dataclasses import dataclass, field | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | from typing import Dict, Union, Optional, Iterable, Sized, Tuple, List | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | from . import options | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | from .data import all_fish, FishItem, all_purchasable_seeds, SeedItem, all_crops, CropItem | 
					
						
							|  |  |  | from .data.bundle_data import BundleItem | 
					
						
							|  |  |  | from .data.museum_data import all_museum_items, MuseumItem | 
					
						
							|  |  |  | from .data.region_data import SVRegion | 
					
						
							|  |  |  | from .data.villagers_data import all_villagers_by_name | 
					
						
							|  |  |  | from .items import all_items, Group | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | from .options import StardewOptions | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | from .stardew_rule import False_, Reach, Or, True_, Received, Count, And, Has, TotalReceived, StardewRule | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | MONEY_PER_MONTH = 15000 | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | MISSING_ITEM = "THIS ITEM IS MISSING" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tool_materials = { | 
					
						
							|  |  |  |     "Copper": 1, | 
					
						
							|  |  |  |     "Iron": 2, | 
					
						
							|  |  |  |     "Gold": 3, | 
					
						
							|  |  |  |     "Iridium": 4 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tool_prices = { | 
					
						
							|  |  |  |     "Copper": 2000, | 
					
						
							|  |  |  |     "Iron": 5000, | 
					
						
							|  |  |  |     "Gold": 10000, | 
					
						
							|  |  |  |     "Iridium": 25000 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | skill_level_per_month_end = { | 
					
						
							|  |  |  |     0: { | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         "Farming": 2, | 
					
						
							|  |  |  |         "Fishing": 2, | 
					
						
							|  |  |  |         "Foraging": 2, | 
					
						
							|  |  |  |         "Mining": 2, | 
					
						
							|  |  |  |         "Combat": 2, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     1: { | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         "Farming": 4, | 
					
						
							|  |  |  |         "Fishing": 4, | 
					
						
							|  |  |  |         "Foraging": 4, | 
					
						
							|  |  |  |         "Mining": 4, | 
					
						
							|  |  |  |         "Combat": 3, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     2: { | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         "Farming": 7, | 
					
						
							|  |  |  |         "Fishing": 5, | 
					
						
							|  |  |  |         "Foraging": 5, | 
					
						
							|  |  |  |         "Mining": 5, | 
					
						
							|  |  |  |         "Combat": 4, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     3: { | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         "Farming": 7, | 
					
						
							|  |  |  |         "Fishing": 7, | 
					
						
							|  |  |  |         "Foraging": 6, | 
					
						
							|  |  |  |         "Mining": 7, | 
					
						
							|  |  |  |         "Combat": 5, | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     4: { | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         "Farming": 10, | 
					
						
							|  |  |  |         "Fishing": 10, | 
					
						
							|  |  |  |         "Foraging": 10, | 
					
						
							|  |  |  |         "Mining": 10, | 
					
						
							|  |  |  |         "Combat": 10, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | month_end_per_skill_level: Dict[Tuple[str, int], int] = {} | 
					
						
							|  |  |  | month_end_per_total_level: Dict[int, int] = {} | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def initialize_season_per_skill_level(): | 
					
						
							|  |  |  |     current_level = { | 
					
						
							|  |  |  |         "Farming": 0, | 
					
						
							|  |  |  |         "Fishing": 0, | 
					
						
							|  |  |  |         "Foraging": 0, | 
					
						
							|  |  |  |         "Mining": 0, | 
					
						
							|  |  |  |         "Combat": 0, | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     for month_end, skills in skill_level_per_month_end.items(): | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         for skill, expected_level in skills.items(): | 
					
						
							|  |  |  |             for level_up in range(current_level[skill] + 1, expected_level + 1): | 
					
						
							|  |  |  |                 skill_level = (skill, level_up) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                 if skill_level not in month_end_per_skill_level: | 
					
						
							|  |  |  |                     month_end_per_skill_level[skill_level] = month_end | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         level_up = 0 | 
					
						
							|  |  |  |         for level_up in range(level_up + 1, sum(skills.values()) + 1): | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             if level_up not in month_end_per_total_level: | 
					
						
							|  |  |  |                 month_end_per_total_level[level_up] = month_end | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | initialize_season_per_skill_level() | 
					
						
							|  |  |  | week_days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | @dataclass(frozen=True, repr=False) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | class StardewLogic: | 
					
						
							|  |  |  |     player: int | 
					
						
							|  |  |  |     options: StardewOptions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     tree_fruit_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							|  |  |  |     seed_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |     crop_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     fish_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     museum_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     building_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							|  |  |  |     quest_rules: Dict[str, StardewRule] = field(default_factory=dict) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __post_init__(self): | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.fish_rules.update({fish.name: self.can_catch_fish(fish) for fish in all_fish}) | 
					
						
							|  |  |  |         self.museum_rules.update({donation.name: self.can_find_museum_item(donation) for donation in all_museum_items}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.tree_fruit_rules.update({ | 
					
						
							|  |  |  |             "Apple": self.has_lived_months(1) & (self.has_season("Fall") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Apricot": self.has_lived_months(1) & (self.has_season("Spring") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Cherry": self.has_lived_months(1) & (self.has_season("Spring") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Orange": self.has_lived_months(1) & (self.has_season("Summer") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Peach": self.has_lived_months(1) & (self.has_season("Summer") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Pomegranate": self.has_lived_months(1) & (self.has_season("Fall") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Banana Sapling": self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Mango Sapling": self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Banana": self.has("Banana Sapling") & (self.has_season("Summer") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |             "Mango": self.has("Mango Sapling") & (self.has_season("Summer") | self.can_reach_region(SVRegion.greenhouse)), | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.seed_rules.update({seed.name: self.can_buy_seed(seed) for seed in all_purchasable_seeds}) | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |         self.crop_rules.update({crop.name: self.can_grow_crop(crop) for crop in all_crops}) | 
					
						
							|  |  |  |         self.crop_rules.update({ | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Coffee Bean": (self.has_season("Spring") | self.has_season("Summer")) & self.has_traveling_merchant(), | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.item_rules.update({ | 
					
						
							|  |  |  |             "Aged Roe": self.has("Preserves Jar") & self.has("Roe"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Algae Soup": self.can_cook() & self.has("Green Algae") & self.has_relationship("Clint", 3), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Any Egg": self.has("Chicken Egg") | self.has("Duck Egg"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Artichoke Dip": self.can_cook() & self.has_season("Fall") & self.has("Artichoke") & self.has("Cow Milk"), | 
					
						
							|  |  |  |             "Artifact Trove": self.has("Omni Geode") & self.can_reach_region(SVRegion.desert), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Bait": self.has_skill_level("Fishing", 2), | 
					
						
							|  |  |  |             "Bat Wing": self.can_mine_in_the_mines_floor_41_80() | self.can_mine_in_the_skull_cavern(), | 
					
						
							|  |  |  |             "Battery Pack": self.has("Lightning Rod"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Bean Hotpot": self.can_cook() & self.has_relationship("Clint", 7) & self.has("Green Bean"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Bee House": self.has_skill_level("Farming", 3) & self.has("Iron Bar") & self.has("Maple Syrup"), | 
					
						
							|  |  |  |             "Beer": (self.has("Keg") & self.has("Wheat")) | self.can_spend_money(400), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Blackberry": self.has_season("Fall"), | 
					
						
							|  |  |  |             "Blackberry Cobbler": self.can_cook() & self.has_season("Fall") & self.has_year_two() & | 
					
						
							|  |  |  |                                   self.has("Blackberry") & self.has("Sugar") & self.has("Wheat Flour"), | 
					
						
							|  |  |  |             "Blueberry Tart": self.has("Blueberry") & self.has("Any Egg") & self.has_relationship("Pierre", 3), | 
					
						
							|  |  |  |             "Bouquet": self.has_relationship("Bachelor", 8), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Bread": self.can_spend_money(120) | (self.can_spend_money(100) & self.can_cook()), | 
					
						
							|  |  |  |             "Broken CD": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Broken Glasses": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Bug Meat": self.can_mine_in_the_mines_floor_1_40(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Cactus Fruit": self.can_reach_region(SVRegion.desert), | 
					
						
							|  |  |  |             "Cave Carrot": self.can_mine_to_floor(10), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Caviar": self.has("Preserves Jar") & self.has("Sturgeon Roe"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Chanterelle": self.has_season("Fall") & self.can_reach_region(SVRegion.secret_woods), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Cheese Press": self.has_skill_level("Farming", 6) & self.has("Hardwood") & self.has("Copper Bar"), | 
					
						
							|  |  |  |             "Cheese": (self.has("Cow Milk") & self.has("Cheese Press")) | | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                       (self.can_reach_region(SVRegion.desert) & self.has("Emerald")), | 
					
						
							|  |  |  |             "Cheese Cauliflower": self.has(["Cheese", "Cauliflower"]) & self.has_relationship("Pam", 3) & | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                                   self.can_cook(), | 
					
						
							|  |  |  |             "Chicken": self.has_building("Coop"), | 
					
						
							|  |  |  |             "Chicken Egg": self.has(["Egg", "Egg (Brown)", "Large Egg", "Large Egg (Brown)"], 1), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Chocolate Cake": self.can_cook() & self.has_season("Winter") & self.has("Wheat Flour") & self.has( | 
					
						
							|  |  |  |                 "Sugar") & self.has("Any Egg"), | 
					
						
							|  |  |  |             "Chowder": self.can_cook() & self.has_relationship("Willy", 3) & self.has(["Clam", "Cow Milk"]), | 
					
						
							|  |  |  |             "Clam": True_(), | 
					
						
							|  |  |  |             "Clay": True_(), | 
					
						
							|  |  |  |             "Glazed Yams": self.can_cook() & self.has_season("Fall") & self.has("Yam") & self.has("Sugar"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Cloth": (self.has("Wool") & self.has("Loom")) | | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                      (self.can_reach_region(SVRegion.desert) & self.has("Aquamarine")), | 
					
						
							|  |  |  |             "Coal": True_(), | 
					
						
							|  |  |  |             "Cockle": True_(), | 
					
						
							|  |  |  |             "Coconut": self.can_reach_region(SVRegion.desert), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Coffee": (self.has("Keg") & self.has("Coffee Bean")) | self.has("Coffee Maker") | | 
					
						
							|  |  |  |                       self.can_spend_money(300) | self.has("Hot Java Ring"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Coffee Maker": False_(), | 
					
						
							|  |  |  |             "Common Mushroom": self.has_season("Fall") | | 
					
						
							|  |  |  |                                (self.has_season("Spring") & self.can_reach_region(SVRegion.secret_woods)), | 
					
						
							|  |  |  |             "Complete Breakfast": self.can_cook() & self.has_season("Spring") & self.has_lived_months(4) & | 
					
						
							|  |  |  |                                   self.has("Fried Egg") & self.has("Cow Milk") & self.has("Hashbrowns") | self.has( | 
					
						
							|  |  |  |                 "Pancakes"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Copper Bar": self.can_smelt("Copper Ore"), | 
					
						
							|  |  |  |             "Copper Ore": self.can_mine_in_the_mines_floor_1_40() | self.can_mine_in_the_skull_cavern(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Coral": self.can_reach_region(SVRegion.tide_pools) | self.has_season("Summer"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Cow": self.has_building("Barn"), | 
					
						
							|  |  |  |             "Cow Milk": self.has("Milk") | self.has("Large Milk"), | 
					
						
							|  |  |  |             "Crab": self.can_crab_pot(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Crab Cakes": self.can_mine_in_the_skull_cavern() | | 
					
						
							|  |  |  |                           (self.can_cook() & self.has_season("Fall") & self.has_year_two() & self.has("Crab") & | 
					
						
							|  |  |  |                            self.has("Wheat Flour") & self.has("Chicken Egg") & self.has("Oil")), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Crab Pot": self.has_skill_level("Fishing", 3), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Cranberry Candy": self.can_cook() & self.has_season("Winter") & self.has("Cranberries") & | 
					
						
							|  |  |  |                                self.has("Apple") & self.has("Sugar"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Crayfish": self.can_crab_pot(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Crispy Bass": self.can_cook() & self.has_relationship("Kent", 3) & self.has("Largemouth Bass") & | 
					
						
							|  |  |  |                            self.has("Wheat Flour") & self.has("Oil"), | 
					
						
							|  |  |  |             "Crocus": self.has_season("Winter"), | 
					
						
							|  |  |  |             "Crystal Fruit": self.has_season("Winter"), | 
					
						
							|  |  |  |             "Daffodil": self.has_season("Spring"), | 
					
						
							|  |  |  |             "Dandelion": self.has_season("Spring"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Dish O' The Sea": self.can_cook() & self.has_skill_level("Fishing", 3) & | 
					
						
							|  |  |  |                                self.has(["Sardine", "Hashbrowns"]), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Dorado": self.can_fish(78) & self.has_season("Summer"), | 
					
						
							|  |  |  |             "Dried Starfish": self.can_fish() & self.can_reach_region(SVRegion.beach), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Driftwood": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Duck Egg": self.has("Duck"), | 
					
						
							|  |  |  |             "Duck Feather": self.has("Duck"), | 
					
						
							|  |  |  |             "Duck": self.has_building("Big Coop"), | 
					
						
							|  |  |  |             "Egg": self.has("Chicken"), | 
					
						
							|  |  |  |             "Egg (Brown)": self.has("Chicken"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Eggplant Parmesan": self.can_cook() & self.has_relationship("Lewis", 7) & self.has("Eggplant") & self.has( | 
					
						
							|  |  |  |                 "Tomato"), | 
					
						
							|  |  |  |             "Escargot": self.can_cook() & self.has_relationship("Willy", 5) & self.has("Snail") & self.has("Garlic"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Farmer's Lunch": self.can_cook() & self.has_skill_level("Farming", 3) & self.has("Omelet") & self.has( | 
					
						
							|  |  |  |                 "Parsnip"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Fiber": True_(), | 
					
						
							|  |  |  |             "Fiddlehead Fern": self.can_reach_region(SVRegion.secret_woods) & self.has_season("Summer"), | 
					
						
							|  |  |  |             "Fiddlehead Risotto": self.can_cook() & self.has_season("Fall") & self.has("Oil") & | 
					
						
							|  |  |  |                                   self.has("Fiddlehead Fern") & self.has("Garlic"), | 
					
						
							|  |  |  |             "Fishing Chest": self.can_fish_chests(), | 
					
						
							|  |  |  |             "Fish Taco": self.can_cook() & self.has_relationship("Linus", 7) & self.has("Tuna") & self.has("Tortilla") & | 
					
						
							|  |  |  |                          self.has("Red Cabbage") & self.has("Mayonnaise"), | 
					
						
							|  |  |  |             "Fried Calamari": self.can_cook() & self.has_relationship("Jodi", 3) & self.has("Squid") & | 
					
						
							|  |  |  |                               self.has("Wheat Flour") & self.has("Oil"), | 
					
						
							|  |  |  |             "Fried Eel": self.can_cook() & self.has_relationship("George", 3) & self.has("Eel") & self.has("Oil"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Fried Egg": self.can_cook() & self.has("Any Egg"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Fried Mushroom": self.can_cook() & self.has_relationship("Demetrius", 3) & self.has( | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                 "Morel") & self.has("Common Mushroom"), | 
					
						
							|  |  |  |             "Frozen Geode": self.can_mine_in_the_mines_floor_41_80(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Fruit Salad": self.can_cook() & self.has_season("Fall") & self.has_year_two() & self.has("Blueberry") & | 
					
						
							|  |  |  |                            self.has("Melon") & self.has("Apricot"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Furnace": self.has("Stone") & self.has("Copper Ore"), | 
					
						
							|  |  |  |             "Geode": self.can_mine_in_the_mines_floor_1_40(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Ginger": self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Ginger Ale": self.can_cook() & self.can_reach_region(SVRegion.ginger_island) & self.has("Ginger") & self.has( | 
					
						
							|  |  |  |                 "Sugar"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Goat Cheese": self.has("Goat Milk") & self.has("Cheese Press"), | 
					
						
							|  |  |  |             "Goat Milk": self.has("Goat"), | 
					
						
							|  |  |  |             "Goat": self.has_building("Big Barn"), | 
					
						
							|  |  |  |             "Gold Bar": self.can_smelt("Gold Ore"), | 
					
						
							|  |  |  |             "Gold Ore": self.can_mine_in_the_mines_floor_81_120() | self.can_mine_in_the_skull_cavern(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Golden Pumpkin": self.has_season("Fall") | self.has("Artifact Trove"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Green Algae": self.can_fish(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Green Tea": self.has("Keg") & self.has("Tea Leaves"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Hardwood": self.has_tool("Axe", "Copper"), | 
					
						
							|  |  |  |             "Hashbrowns": self.can_cook() & self.can_spend_money(50) & self.has("Potato"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Hazelnut": self.has_season("Fall"), | 
					
						
							|  |  |  |             "Holly": self.has_season("Winter"), | 
					
						
							|  |  |  |             "Honey": self.can_reach_region(SVRegion.desert) | | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                      (self.has("Bee House") & | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                       (self.has_season("Spring") | self.has_season("Summer") | self.has_season("Fall"))), | 
					
						
							|  |  |  |             "Hot Java Ring": self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Ice Cream": (self.has_season("Summer") & self.can_reach_region(SVRegion.town)) | self.can_reach_region( | 
					
						
							|  |  |  |                 "The Desert"), | 
					
						
							|  |  |  |             # | (self.can_cook() & self.has_relationship("Jodi", 7) & self.has("Cow Milk") & self.has("Sugar")), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Iridium Bar": self.can_smelt("Iridium Ore"), | 
					
						
							|  |  |  |             "Iridium Ore": self.can_mine_in_the_skull_cavern(), | 
					
						
							|  |  |  |             "Iron Bar": self.can_smelt("Iron Ore"), | 
					
						
							|  |  |  |             "Iron Ore": self.can_mine_in_the_mines_floor_41_80() | self.can_mine_in_the_skull_cavern(), | 
					
						
							|  |  |  |             "Jelly": self.has("Preserves Jar"), | 
					
						
							|  |  |  |             "JotPK Small Buff": self.has_jotpk_power_level(2), | 
					
						
							|  |  |  |             "JotPK Medium Buff": self.has_jotpk_power_level(4), | 
					
						
							|  |  |  |             "JotPK Big Buff": self.has_jotpk_power_level(7), | 
					
						
							|  |  |  |             "JotPK Max Buff": self.has_jotpk_power_level(9), | 
					
						
							|  |  |  |             "Juice": self.has("Keg"), | 
					
						
							|  |  |  |             "Junimo Kart Small Buff": self.has_junimo_kart_power_level(2), | 
					
						
							|  |  |  |             "Junimo Kart Medium Buff": self.has_junimo_kart_power_level(4), | 
					
						
							|  |  |  |             "Junimo Kart Big Buff": self.has_junimo_kart_power_level(6), | 
					
						
							|  |  |  |             "Junimo Kart Max Buff": self.has_junimo_kart_power_level(8), | 
					
						
							|  |  |  |             "Keg": self.has_skill_level("Farming", 8) & self.has("Iron Bar") & self.has("Copper Bar") & self.has( | 
					
						
							|  |  |  |                 "Oak Resin"), | 
					
						
							|  |  |  |             "Large Egg": self.has("Chicken"), | 
					
						
							|  |  |  |             "Large Egg (Brown)": self.has("Chicken"), | 
					
						
							|  |  |  |             "Large Goat Milk": self.has("Goat"), | 
					
						
							|  |  |  |             "Large Milk": self.has("Cow"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Leek": self.has_season("Spring"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Lightning Rod": self.has_skill_level("Foraging", 6), | 
					
						
							|  |  |  |             "Lobster": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Loom": self.has_skill_level("Farming", 7) & self.has("Pine Tar"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Magic Rock Candy": self.can_reach_region(SVRegion.desert) & self.has("Prismatic Shard"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Magma Geode": self.can_mine_in_the_mines_floor_81_120() | | 
					
						
							|  |  |  |                            (self.has("Lava Eel") & self.has_building("Fish Pond")), | 
					
						
							|  |  |  |             "Maki Roll": self.can_cook() & self.can_fish(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Maple Bar": self.can_cook() & self.has_season("Summer") & self.has_year_two() & self.has("Maple Syrup") & | 
					
						
							|  |  |  |                          self.has("Sugar") & self.has("Wheat Flour"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Maple Syrup": self.has("Tapper"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Mayonnaise": self.has("Mayonnaise Machine") & self.has("Chicken Egg"), | 
					
						
							|  |  |  |             "Mayonnaise Machine": self.has_skill_level("Farming", 2) & self.has("Wood") & self.has("Stone") & | 
					
						
							|  |  |  |                                   self.has("Earth Crystal") & self.has("Copper Bar"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Mead": self.has("Keg") & self.has("Honey"), | 
					
						
							|  |  |  |             "Milk": self.has("Cow"), | 
					
						
							|  |  |  |             "Miner's Treat": self.can_cook() & self.has_skill_level("Mining", 3) & self.has("Cow Milk") & self.has( | 
					
						
							|  |  |  |                 "Cave Carrot"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Morel": self.can_reach_region(SVRegion.secret_woods), | 
					
						
							|  |  |  |             "Mussel": True_(), | 
					
						
							|  |  |  |             "Nautilus Shell": self.has_season("Winter"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Oak Resin": self.has("Tapper"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Oil": True_(), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Oil Maker": self.has_skill_level("Farming", 8) & self.has("Hardwood") & self.has("Gold Bar"), | 
					
						
							|  |  |  |             "Omelet": self.can_cook() & self.can_spend_money(100) & self.has("Any Egg") & self.has("Cow Milk"), | 
					
						
							|  |  |  |             "Omni Geode": self.can_mine_in_the_mines_floor_41_80() | | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                           self.can_reach_region(SVRegion.desert) | | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                           self.can_do_panning() | | 
					
						
							|  |  |  |                           self.received("Rusty Key") | | 
					
						
							|  |  |  |                           (self.has("Octopus") & self.has_building("Fish Pond")) | | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                           self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Ostrich": self.has_building("Barn") & self.has("Ostrich Egg"), | 
					
						
							|  |  |  |             "Ostrich Egg": self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Oyster": True_(), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Pale Ale": self.has("Keg") & self.has("Hops"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Pale Broth": self.can_cook() & self.has_relationship("Marnie", 3) & self.has("White Algae"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Pancakes": self.can_cook() & self.can_spend_money(100) & self.has("Any Egg"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Parsnip Soup": self.can_cook() & self.has_relationship("Caroline", 3) & self.has( | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                 "Parsnip") & self.has("Cow Milk"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Pearl": (self.has("Blobfish") & self.has_building("Fish Pond")) | | 
					
						
							|  |  |  |                      (self.has_lived_months(4) & self.has("Artifact Trove")), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Pepper Poppers": self.can_cook() & self.has("Cheese") & self.has( | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                 "Hot Pepper") & self.has_relationship("Shane", 3), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Periwinkle": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Pickles": self.has("Preserves Jar"), | 
					
						
							|  |  |  |             "Pig": self.has_building("Deluxe Barn"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Piña Colada": False_(),  # self.can_reach_region(SVRegion.ginger_island), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Pine Tar": self.has("Tapper"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Pink Cake": self.can_cook() & self.has_season("Summer") & self.has("Melon") & self.has( | 
					
						
							|  |  |  |                 "Wheat Flour") & self.has("Sugar") & self.has("Any Egg"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Pizza": self.can_spend_money(600), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Plum Pudding": self.can_cook() & self.has_season("Winter") & self.has("Wild Plum") & | 
					
						
							|  |  |  |                             self.has("Wheat Flour") & self.has("Sugar"), | 
					
						
							|  |  |  |             "Poppyseed Muffin": self.can_cook() & self.has_season("Winter") & self.has_year_two() & | 
					
						
							|  |  |  |                                 self.has("Poppy") & self.has("Wheat Flour") & self.has("Sugar"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Preserves Jar": self.has_skill_level("Farming", 4), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Pumpkin Pie": self.can_cook() & self.has_season("Winter") & self.has("Wheat Flour") & | 
					
						
							|  |  |  |                            self.has("Cow Milk") & self.has("Sugar"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Purple Mushroom": self.can_mine_in_the_mines_floor_81_120() | self.can_mine_in_the_skull_cavern(), | 
					
						
							|  |  |  |             "Rabbit": self.has_building("Deluxe Coop"), | 
					
						
							|  |  |  |             "Rabbit's Foot": self.has("Rabbit"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Radioactive Bar": self.can_smelt("Radioactive Ore"), | 
					
						
							|  |  |  |             "Radioactive Ore": self.can_mine_perfectly_in_the_skull_cavern() & self.can_reach_region(SVRegion.ginger_island), | 
					
						
							|  |  |  |             "Rainbow Shell": self.has_season("Summer"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Rain Totem": self.has_skill_level("Foraging", 9), | 
					
						
							|  |  |  |             "Recycling Machine": self.has_skill_level("Fishing", 4) & self.has("Wood") & | 
					
						
							|  |  |  |                                  self.has("Stone") & self.has("Iron Bar"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Red Mushroom": self.can_reach_region(SVRegion.secret_woods) & ( | 
					
						
							|  |  |  |                     self.has_season("Summer") | self.has_season("Fall")), | 
					
						
							|  |  |  |             "Refined Quartz": self.can_smelt("Quartz") | self.can_smelt("Fire Quartz") | | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                               (self.has("Recycling Machine") & (self.has("Broken CD") | self.has("Broken Glasses"))), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Rhubarb Pie": self.can_cook() & self.has_relationship("Marnie", 7) & self.has("Rhubarb") & | 
					
						
							|  |  |  |                            self.has("Wheat Flour") & self.has("Sugar"), | 
					
						
							|  |  |  |             "Rice": True_(), | 
					
						
							|  |  |  |             "Rice Pudding": self.can_cook() & self.has_relationship("Evelyn", 7) & self.has("Cow Milk") & | 
					
						
							|  |  |  |                             self.has("Sugar") & self.has("Rice"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Roe": self.can_fish() & self.has_building("Fish Pond"), | 
					
						
							|  |  |  |             "Roots Platter": self.can_cook() & self.has_skill_level("Combat", 3) & | 
					
						
							|  |  |  |                              self.has("Cave Carrot") & self.has("Winter Root"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Roasted Hazelnuts": self.can_cook() & self.has_season("Summer") & self.has("Hazelnut"), | 
					
						
							|  |  |  |             "Salad": self.can_spend_money(220), | 
					
						
							|  |  |  |             # | (self.can_cook() & self.has_relationship("Emily", 3) & self.has("Leek") & self.has("Dandelion") & self.has("Vinegar")), | 
					
						
							|  |  |  |             "Salmonberry": self.has_season("Spring"), | 
					
						
							|  |  |  |             "Salmon Dinner": self.can_cook() & self.has_relationship("Gus", 3) & self.has("Salmon") & self.has( | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                 "Amaranth") & self.has("Kale"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Sashimi": self.can_fish() & self.can_cook() & self.has_relationship("Linus", 3), | 
					
						
							|  |  |  |             "Sea Urchin": self.can_reach_region(SVRegion.tide_pools) | self.has_season("Summer"), | 
					
						
							|  |  |  |             "Seaweed": self.can_fish() | self.can_reach_region(SVRegion.tide_pools), | 
					
						
							|  |  |  |             "Secret Note": self.received("Magnifying Glass"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Sheep": self.has_building("Deluxe Barn"), | 
					
						
							|  |  |  |             "Shrimp": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Slime": self.can_mine_in_the_mines_floor_1_40(), | 
					
						
							|  |  |  |             "Snail": self.can_crab_pot(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Snow Yam": self.has_season("Winter"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Soggy Newspaper": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Solar Essence": self.can_mine_in_the_mines_floor_41_80() | self.can_mine_in_the_skull_cavern(), | 
					
						
							|  |  |  |             "Spaghetti": self.can_spend_money(240), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Spice Berry": self.has_season("Summer"), | 
					
						
							|  |  |  |             "Spring Onion": self.has_season("Spring"), | 
					
						
							|  |  |  |             "Squid Ink": self.can_mine_in_the_mines_floor_81_120() | ( | 
					
						
							|  |  |  |                     self.has_building("Fish Pond") & self.has("Squid")), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Staircase": self.has_skill_level("Mining", 2), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Stir Fry": self.can_cook() & self.has_season("Spring") & self.has("Cave Carrot") & | 
					
						
							|  |  |  |                         self.has("Common Mushroom") & self.has("Kale") & self.has("Oil"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Stone": self.has_tool("Pickaxe"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Stuffing": self.has_season("Winter") | | 
					
						
							|  |  |  |                         (self.can_cook() & self.has_relationship("Pam", 7) & self.has("Bread") & | 
					
						
							|  |  |  |                          self.has("Cranberries") & self.has("Hazelnut")), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Sturgeon Roe": self.has("Sturgeon") & self.has_building("Fish Pond"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Sugar": True_(), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Survival Burger": self.can_cook() & self.has_skill_level("Foraging", 2) & | 
					
						
							|  |  |  |                                self.has(["Bread", "Cave Carrot", "Eggplant"]), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Sweet Pea": self.has_season("Summer"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Tapper": self.has_skill_level("Foraging", 3), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Tea Bush": self.has_relationship("Caroline", 2), | 
					
						
							|  |  |  |             "Tea Leaves": self.has_lived_months(1) & self.has("Tea Bush"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Tortilla": self.can_cook() & self.can_spend_money(100) & self.has("Corn"), | 
					
						
							|  |  |  |             "Trash": self.can_crab_pot(), | 
					
						
							|  |  |  |             "Triple Shot Espresso": (self.has("Hot Java Ring") | | 
					
						
							|  |  |  |                                      (self.can_cook() & self.can_spend_money(5000) & self.has("Coffee"))), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Tropical Curry": False_(), | 
					
						
							|  |  |  |             # self.can_cook() & self.can_reach_region(SVRegion.ginger_island) & self.has("Coconut") & self.has("Pineapple") & self.has("Hot Pepper"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Truffle Oil": self.has("Truffle") & self.has("Oil Maker"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Truffle": self.has("Pig") & self.has_spring_summer_or_fall(), | 
					
						
							|  |  |  |             "Vegetable Medley": self.can_cook() & self.has_relationship("Caroline", 7) & self.has("Tomato") & self.has( | 
					
						
							|  |  |  |                 "Beet"), | 
					
						
							|  |  |  |             "Vinegar": True_(), | 
					
						
							|  |  |  |             "Void Egg": self.can_meet("Krobus") | (self.has_building("Fish Pond") & self.has("Void Salmon")), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Void Essence": self.can_mine_in_the_mines_floor_81_120() | self.can_mine_in_the_skull_cavern(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Void Mayonnaise": self.has("Mayonnaise Machine") & self.has("Void Egg"), | 
					
						
							|  |  |  |             "Wheat Flour": True_(), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "White Algae": self.can_fish() & self.can_mine_in_the_mines_floor_1_40(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Wild Horseradish": self.has_season("Spring"), | 
					
						
							|  |  |  |             "Wild Plum": self.has_season("Fall"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Wilted Bouquet": self.has("Furnace") & self.has("Bouquet") & self.has("Coal"), | 
					
						
							|  |  |  |             "Wine": self.has("Keg"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Winter Root": self.has_season("Winter"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Wood": self.has_tool("Axe"), | 
					
						
							|  |  |  |             "Wool": self.has("Rabbit") | self.has("Sheep"), | 
					
						
							|  |  |  |             "Hay": self.has_building("Silo"), | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         self.item_rules.update(self.fish_rules) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         self.item_rules.update(self.museum_rules) | 
					
						
							|  |  |  |         self.item_rules.update(self.tree_fruit_rules) | 
					
						
							|  |  |  |         self.item_rules.update(self.seed_rules) | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |         self.item_rules.update(self.crop_rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.building_rules.update({ | 
					
						
							|  |  |  |             "Barn": self.can_spend_money(6000) & self.has(["Wood", "Stone"]), | 
					
						
							|  |  |  |             "Big Barn": self.can_spend_money(12000) & self.has(["Wood", "Stone"]) & self.has_building("Barn"), | 
					
						
							|  |  |  |             "Deluxe Barn": self.can_spend_money(25000) & self.has(["Wood", "Stone"]) & self.has_building("Big Barn"), | 
					
						
							|  |  |  |             "Coop": self.can_spend_money(4000) & self.has(["Wood", "Stone"]), | 
					
						
							|  |  |  |             "Big Coop": self.can_spend_money(10000) & self.has(["Wood", "Stone"]) & self.has_building("Coop"), | 
					
						
							|  |  |  |             "Deluxe Coop": self.can_spend_money(20000) & self.has(["Wood", "Stone"]) & self.has_building("Big Coop"), | 
					
						
							|  |  |  |             "Fish Pond": self.can_spend_money(5000) & self.has(["Stone", "Seaweed", "Green Algae"]), | 
					
						
							|  |  |  |             "Mill": self.can_spend_money(2500) & self.has(["Stone", "Wood", "Cloth"]), | 
					
						
							|  |  |  |             "Shed": self.can_spend_money(15000) & self.has("Wood"), | 
					
						
							|  |  |  |             "Big Shed": self.can_spend_money(20000) & self.has(["Wood", "Stone"]) & self.has_building("Shed"), | 
					
						
							|  |  |  |             "Silo": self.can_spend_money(100) & self.has(["Stone", "Clay", "Copper Bar"]), | 
					
						
							|  |  |  |             "Slime Hutch": self.can_spend_money(10000) & self.has(["Stone", "Refined Quartz", "Iridium Bar"]), | 
					
						
							|  |  |  |             "Stable": self.can_spend_money(10000) & self.has(["Hardwood", "Iron Bar"]), | 
					
						
							|  |  |  |             "Well": self.can_spend_money(1000) & self.has("Stone"), | 
					
						
							|  |  |  |             "Shipping Bin": self.can_spend_money(250) & self.has("Wood"), | 
					
						
							|  |  |  |             "Kitchen": self.can_spend_money(10000) & self.has("Wood") & self.has_house(0), | 
					
						
							|  |  |  |             "Kids Room": self.can_spend_money(50000) & self.has("Hardwood") & self.has_house(1), | 
					
						
							|  |  |  |             "Cellar": self.can_spend_money(100000) & self.has_house(2), | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.quest_rules.update({ | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Introductions": True_(), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "How To Win Friends": self.can_complete_quest("Introductions"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Getting Started": self.has("Parsnip") & self.has_tool("Hoe") & self.has_tool("Watering Can"), | 
					
						
							|  |  |  |             "To The Beach": True_(), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Raising Animals": self.can_complete_quest("Getting Started") & self.has_building("Coop"), | 
					
						
							|  |  |  |             "Advancement": self.can_complete_quest("Getting Started") & self.has_skill_level("Farming", 1), | 
					
						
							|  |  |  |             "Archaeology": self.has_tool("Hoe") | self.can_mine_in_the_mines_floor_1_40() | self.can_fish(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Meet The Wizard": True_() & self.can_reach_region(SVRegion.community_center), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Forging Ahead": self.has("Copper Ore") & self.has("Furnace"), | 
					
						
							|  |  |  |             "Smelting": self.has("Copper Bar"), | 
					
						
							|  |  |  |             "Initiation": self.can_mine_in_the_mines_floor_1_40(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Robin's Lost Axe": self.has_season("Spring"), | 
					
						
							|  |  |  |             "Jodi's Request": self.has_season("Spring") & self.has("Cauliflower"), | 
					
						
							|  |  |  |             "Mayor's \"Shorts\"": self.has_season("Summer") & self.has_relationship("Marnie", 4), | 
					
						
							|  |  |  |             "Blackberry Basket": self.has_season("Fall"), | 
					
						
							|  |  |  |             "Marnie's Request": self.has_relationship("Marnie", 3) & self.has("Cave Carrot"), | 
					
						
							|  |  |  |             "Pam Is Thirsty": self.has_season("Summer") & self.has("Pale Ale"), | 
					
						
							|  |  |  |             "A Dark Reagent": self.has_season("Winter") & self.has("Void Essence"), | 
					
						
							|  |  |  |             "Cow's Delight": self.has_season("Fall") & self.has("Amaranth"), | 
					
						
							|  |  |  |             "The Skull Key": self.received("Skull Key") & self.can_reach_region(SVRegion.desert), | 
					
						
							|  |  |  |             "Crop Research": self.has_season("Summer") & self.has("Melon"), | 
					
						
							|  |  |  |             "Knee Therapy": self.has_season("Summer") & self.has("Hot Pepper"), | 
					
						
							|  |  |  |             "Robin's Request": self.has_season("Winter") & self.has("Hardwood"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             "Qi's Challenge": self.can_mine_in_the_skull_cavern(), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "The Mysterious Qi": self.has("Battery Pack") & self.can_reach_region(SVRegion.desert) & self.has( | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                 "Rainbow Shell") & self.has("Beet") & self.has("Solar Essence"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Carving Pumpkins": self.has_season("Fall") & self.has("Pumpkin"), | 
					
						
							|  |  |  |             "A Winter Mystery": self.has_season("Winter"), | 
					
						
							|  |  |  |             "Strange Note": self.received("Magnifying Glass") & self.can_reach_region(SVRegion.secret_woods) & self.has( | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                 "Maple Syrup"), | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             "Cryptic Note": self.received("Magnifying Glass") & self.can_reach_region(SVRegion.perfect_skull_cavern), | 
					
						
							|  |  |  |             "Fresh Fruit": self.has("Apricot"), | 
					
						
							|  |  |  |             "Aquatic Research": self.has("Pufferfish"), | 
					
						
							|  |  |  |             "A Soldier's Star": self.has_relationship("Kent") & self.has("Starfruit"), | 
					
						
							|  |  |  |             "Mayor's Need": self.has("Truffle Oil"), | 
					
						
							|  |  |  |             "Wanted: Lobster": self.has("Lobster"), | 
					
						
							|  |  |  |             "Pam Needs Juice": self.has("Battery Pack"), | 
					
						
							|  |  |  |             "Fish Casserole": self.has_relationship("Jodi", 4) & self.has("Largemouth Bass"), | 
					
						
							|  |  |  |             "Catch A Squid": self.has("Squid"), | 
					
						
							|  |  |  |             "Fish Stew": self.has("Albacore"), | 
					
						
							|  |  |  |             "Pierre's Notice": self.has("Sashimi"), | 
					
						
							|  |  |  |             "Clint's Attempt": self.has("Amethyst"), | 
					
						
							|  |  |  |             "A Favor For Clint": self.has("Iron Bar"), | 
					
						
							|  |  |  |             "Staff Of Power": self.has("Iridium Bar"), | 
					
						
							|  |  |  |             "Granny's Gift": self.has("Leek"), | 
					
						
							|  |  |  |             "Exotic Spirits": self.has("Coconut"), | 
					
						
							|  |  |  |             "Catch a Lingcod": self.has("Lingcod"), | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has(self, items: Union[str, (Iterable[str], Sized)], count: Optional[int] = None) -> StardewRule: | 
					
						
							|  |  |  |         if isinstance(items, str): | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return Has(items, self.item_rules) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if len(items) == 0: | 
					
						
							|  |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if count is None or count == len(items): | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return And(self.has(item) for item in items) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if count == 1: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return Or(self.has(item) for item in items) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Count(count, (self.has(item) for item in items)) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def received(self, items: Union[str, Iterable[str]], count: Optional[int] = 1) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         if count <= 0 or not items: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         if isinstance(items, str): | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return Received(items, self.player, count) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if count is None: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return And(self.received(item) for item in items) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if count == 1: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return Or(self.received(item) for item in items) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return TotalReceived(count, items, self.player) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_reach_region(self, spot: str) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Reach(spot, "Region", self.player) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_reach_any_region(self, spots: Iterable[str]) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Or(self.can_reach_region(spot) for spot in spots) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_reach_all_regions(self, spots: Iterable[str]) -> StardewRule: | 
					
						
							|  |  |  |         return And(self.can_reach_region(spot) for spot in spots) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_reach_location(self, spot: str) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Reach(spot, "Location", self.player) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_reach_entrance(self, spot: str) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Reach(spot, "Entrance", self.player) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_have_earned_total_money(self, amount: int) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.has_lived_months(min(8, amount // MONEY_PER_MONTH)) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_spend_money(self, amount: int) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.has_lived_months(min(8, amount // (MONEY_PER_MONTH // 5))) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_tool(self, tool: str, material: str = "Basic") -> StardewRule: | 
					
						
							|  |  |  |         if material == "Basic": | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             return self.received(f"Progressive {tool}", count=tool_materials[material]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return self.has(f"{material} Bar") & self.can_spend_money(tool_prices[material]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_skill_level(self, skill: str, level: int) -> StardewRule: | 
					
						
							|  |  |  |         if level == 0: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.options[options.SkillProgression] == options.SkillProgression.option_progressive: | 
					
						
							|  |  |  |             return self.received(f"{skill} Level", count=level) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if skill == "Fishing" and self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             return self.can_get_fishing_xp() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.has_lived_months(month_end_per_skill_level[(skill, level)]) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_total_skill_level(self, level: int) -> StardewRule: | 
					
						
							|  |  |  |         if level == 0: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.options[options.SkillProgression] == options.SkillProgression.option_progressive: | 
					
						
							|  |  |  |             skills_items = ["Farming Level", "Mining Level", "Foraging Level", | 
					
						
							|  |  |  |                             "Fishing Level", "Combat Level"] | 
					
						
							|  |  |  |             return self.received(skills_items, count=level) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if level > 40 and self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return self.has_lived_months(month_end_per_total_level[level]) & self.can_get_fishing_xp() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.has_lived_months(month_end_per_total_level[level]) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_building(self, building: str) -> StardewRule: | 
					
						
							|  |  |  |         if not self.options[options.BuildingProgression] == options.BuildingProgression.option_vanilla: | 
					
						
							|  |  |  |             count = 1 | 
					
						
							|  |  |  |             if building in ["Coop", "Barn", "Shed"]: | 
					
						
							|  |  |  |                 building = f"Progressive {building}" | 
					
						
							|  |  |  |             elif building.startswith("Big"): | 
					
						
							|  |  |  |                 count = 2 | 
					
						
							|  |  |  |                 building = " ".join(["Progressive", *building.split(" ")[1:]]) | 
					
						
							|  |  |  |             elif building.startswith("Deluxe"): | 
					
						
							|  |  |  |                 count = 3 | 
					
						
							|  |  |  |                 building = " ".join(["Progressive", *building.split(" ")[1:]]) | 
					
						
							|  |  |  |             return self.received(f"{building}", count) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Has(building, self.building_rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_house(self, upgrade_level: int) -> StardewRule: | 
					
						
							|  |  |  |         if upgrade_level < 1: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if upgrade_level > 3: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return False_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not self.options[options.BuildingProgression] == options.BuildingProgression.option_vanilla: | 
					
						
							|  |  |  |             return self.received(f"Progressive House", upgrade_level) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if upgrade_level == 1: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return Has("Kitchen", self.building_rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if upgrade_level == 2: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return Has("Kids Room", self.building_rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # if upgrade_level == 3: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Has("Cellar", self.building_rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_complete_quest(self, quest: str) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Has(quest, self.quest_rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_get_fishing_xp(self) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.SkillProgression] == options.SkillProgression.option_progressive: | 
					
						
							|  |  |  |             return self.can_fish() | self.can_crab_pot() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return self.can_fish() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     def has_max_fishing_rod(self) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             return self.received("Progressive Fishing Rod", 4) | 
					
						
							|  |  |  |         return self.can_get_fishing_xp() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     def can_fish(self, difficulty: int = 0) -> StardewRule: | 
					
						
							|  |  |  |         skill_required = max(0, int((difficulty / 10) - 1)) | 
					
						
							|  |  |  |         if difficulty <= 40: | 
					
						
							|  |  |  |             skill_required = 0 | 
					
						
							|  |  |  |         skill_rule = self.has_skill_level("Fishing", skill_required) | 
					
						
							|  |  |  |         number_fishing_rod_required = 1 if difficulty < 50 else 2 | 
					
						
							|  |  |  |         if self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             return self.received("Progressive Fishing Rod", number_fishing_rod_required) & skill_rule | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return skill_rule | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |     def has_max_fishing(self) -> StardewRule: | 
					
						
							|  |  |  |         skill_rule = self.has_skill_level("Fishing", 10) | 
					
						
							|  |  |  |         return self.has_max_fishing_rod() & skill_rule | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_fish_chests(self) -> StardewRule: | 
					
						
							|  |  |  |         skill_rule = self.has_skill_level("Fishing", 4) | 
					
						
							|  |  |  |         return self.has_max_fishing_rod() & skill_rule | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_buy_seed(self, seed: SeedItem): | 
					
						
							|  |  |  |         if self.options[options.SeedShuffle] == options.SeedShuffle.option_disabled or seed.name == "Rare Seed": | 
					
						
							|  |  |  |             item_rule = True_() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             item_rule = self.received(seed.name) | 
					
						
							|  |  |  |         season_rule = self.has_any_season(seed.seasons) | 
					
						
							|  |  |  |         region_rule = self.can_reach_any_region(seed.regions) | 
					
						
							|  |  |  |         return season_rule & region_rule & item_rule | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_grow_crop(self, crop: CropItem): | 
					
						
							|  |  |  |         season_rule = self.has_any_season(crop.farm_growth_seasons) | 
					
						
							|  |  |  |         seed_rule = self.has(crop.seed.name) | 
					
						
							|  |  |  |         farm_rule = self.can_reach_region(SVRegion.farm) & season_rule | 
					
						
							|  |  |  |         region_rule = farm_rule | self.can_reach_region(SVRegion.greenhouse) | 
					
						
							|  |  |  |         return seed_rule & region_rule | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     def can_catch_fish(self, fish: FishItem) -> StardewRule: | 
					
						
							|  |  |  |         region_rule = self.can_reach_any_region(fish.locations) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         season_rule = self.has_any_season(fish.seasons) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         difficulty_rule = self.can_fish(fish.difficulty) | 
					
						
							|  |  |  |         if fish.difficulty == -1: | 
					
						
							|  |  |  |             difficulty_rule = self.can_crab_pot() | 
					
						
							|  |  |  |         return region_rule & season_rule & difficulty_rule | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_catch_every_fish(self) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-03-04 12:34:51 -05:00
										 |  |  |         rules = [self.has_skill_level("Fishing", 10), self.has_max_fishing_rod()] | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         for fish in all_fish: | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |             rules.append(self.can_catch_fish(fish)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return And(rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-04 12:34:51 -05:00
										 |  |  |     def has_max_fishing_rod(self) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             return self.received("Progressive Fishing Rod", 4) | 
					
						
							|  |  |  |         return self.can_get_fishing_xp() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |     def can_cook(self) -> StardewRule: | 
					
						
							|  |  |  |         return self.has_house(1) or self.has_skill_level("Foraging", 9) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_smelt(self, item: str) -> StardewRule: | 
					
						
							|  |  |  |         return self.has("Furnace") & self.has(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_crab_pot(self) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.SkillProgression] == options.SkillProgression.option_progressive: | 
					
						
							|  |  |  |             return self.has("Crab Pot") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_do_panning(self) -> StardewRule: | 
					
						
							|  |  |  |         return self.received("Glittering Boulder Removed") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Regions | 
					
						
							|  |  |  |     def can_mine_in_the_mines_floor_1_40(self) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.can_reach_region(SVRegion.mines_floor_5) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_mine_in_the_mines_floor_41_80(self) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.can_reach_region(SVRegion.mines_floor_45) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_mine_in_the_mines_floor_81_120(self) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.can_reach_region(SVRegion.mines_floor_85) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_mine_in_the_skull_cavern(self) -> StardewRule: | 
					
						
							|  |  |  |         return (self.can_progress_in_the_mines_from_floor(120) & | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                 self.can_reach_region(SVRegion.skull_cavern)) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_mine_perfectly_in_the_skull_cavern(self) -> StardewRule: | 
					
						
							|  |  |  |         return (self.can_progress_in_the_mines_from_floor(160) & | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                 self.can_reach_region(SVRegion.skull_cavern)) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_weapon_rule_for_floor_tier(self, tier: int): | 
					
						
							|  |  |  |         if tier >= 4: | 
					
						
							|  |  |  |             return self.has_galaxy_weapon() | 
					
						
							|  |  |  |         if tier >= 3: | 
					
						
							|  |  |  |             return self.has_great_weapon() | 
					
						
							|  |  |  |         if tier >= 2: | 
					
						
							|  |  |  |             return self.has_good_weapon() | 
					
						
							|  |  |  |         if tier >= 1: | 
					
						
							|  |  |  |             return self.has_decent_weapon() | 
					
						
							|  |  |  |         return self.has_any_weapon() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_progress_in_the_mines_from_floor(self, floor: int) -> StardewRule: | 
					
						
							|  |  |  |         tier = int(floor / 40) | 
					
						
							|  |  |  |         rules = [] | 
					
						
							|  |  |  |         weapon_rule = self.get_weapon_rule_for_floor_tier(tier) | 
					
						
							|  |  |  |         rules.append(weapon_rule) | 
					
						
							|  |  |  |         if self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             rules.append(self.received("Progressive Pickaxe", tier)) | 
					
						
							|  |  |  |         if self.options[options.SkillProgression] == options.SkillProgression.option_progressive: | 
					
						
							|  |  |  |             combat_tier = min(10, max(0, tier * 2)) | 
					
						
							|  |  |  |             rules.append(self.has_skill_level("Combat", combat_tier)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return And(rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_progress_easily_in_the_mines_from_floor(self, floor: int) -> StardewRule: | 
					
						
							|  |  |  |         tier = int(floor / 40) + 1 | 
					
						
							|  |  |  |         rules = [] | 
					
						
							|  |  |  |         weapon_rule = self.get_weapon_rule_for_floor_tier(tier) | 
					
						
							|  |  |  |         rules.append(weapon_rule) | 
					
						
							|  |  |  |         if self.options[options.ToolProgression] == options.ToolProgression.option_progressive: | 
					
						
							|  |  |  |             rules.append(self.received("Progressive Pickaxe", count=tier)) | 
					
						
							|  |  |  |         if self.options[options.SkillProgression] == options.SkillProgression.option_progressive: | 
					
						
							|  |  |  |             combat_tier = min(10, max(0, tier * 2)) | 
					
						
							|  |  |  |             rules.append(self.has_skill_level("Combat", combat_tier)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return And(rules) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_mine_elevator_to_floor(self, floor: int) -> StardewRule: | 
					
						
							|  |  |  |         if (self.options[options.TheMinesElevatorsProgression] == | 
					
						
							|  |  |  |                 options.TheMinesElevatorsProgression.option_progressive or | 
					
						
							|  |  |  |                 self.options[options.TheMinesElevatorsProgression] == | 
					
						
							|  |  |  |                 options.TheMinesElevatorsProgression.option_progressive_from_previous_floor): | 
					
						
							|  |  |  |             return self.received("Progressive Mine Elevator", count=int(floor / 5)) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_mine_to_floor(self, floor: int) -> StardewRule: | 
					
						
							|  |  |  |         previous_elevator = max(floor - 5, 0) | 
					
						
							|  |  |  |         previous_previous_elevator = max(floor - 10, 0) | 
					
						
							|  |  |  |         return ((self.has_mine_elevator_to_floor(previous_elevator) & | 
					
						
							|  |  |  |                  self.can_progress_in_the_mines_from_floor(previous_elevator)) | | 
					
						
							|  |  |  |                 (self.has_mine_elevator_to_floor(previous_previous_elevator) & | 
					
						
							|  |  |  |                  self.can_progress_easily_in_the_mines_from_floor(previous_previous_elevator))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_jotpk_power_level(self, power_level: int) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.ArcadeMachineLocations] != options.ArcadeMachineLocations.option_full_shuffling: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         jotpk_buffs = ["JotPK: Progressive Boots", "JotPK: Progressive Gun", | 
					
						
							|  |  |  |                        "JotPK: Progressive Ammo", "JotPK: Extra Life", "JotPK: Increased Drop Rate"] | 
					
						
							|  |  |  |         return self.received(jotpk_buffs, power_level) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_junimo_kart_power_level(self, power_level: int) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.ArcadeMachineLocations] != options.ArcadeMachineLocations.option_full_shuffling: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return True_() | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         return self.received("Junimo Kart: Extra Life", power_level) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_traveling_merchant(self, tier: int = 1): | 
					
						
							|  |  |  |         traveling_merchant_days = [f"Traveling Merchant: {day}" for day in week_days] | 
					
						
							|  |  |  |         return self.received(traveling_merchant_days, tier) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_get_married(self) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return self.can_reach_region(SVRegion.tide_pools) & self.has_relationship("Bachelor", 10) & self.has_house(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_have_two_children(self) -> StardewRule: | 
					
						
							|  |  |  |         return self.can_get_married() & self.has_house(2) & self.has_relationship("Bachelor", 12) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_relationship(self, npc: str, hearts: int = 1) -> StardewRule: | 
					
						
							|  |  |  |         if hearts <= 0: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  |         if self.options[options.Friendsanity] == options.Friendsanity.option_none: | 
					
						
							|  |  |  |             return self.can_earn_relationship(npc, hearts) | 
					
						
							|  |  |  |         if npc not in all_villagers_by_name: | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |             if npc == "Pet": | 
					
						
							|  |  |  |                 if self.options[options.Friendsanity] == options.Friendsanity.option_bachelors: | 
					
						
							|  |  |  |                     return self.can_befriend_pet(hearts) | 
					
						
							|  |  |  |                 return self.received(f"Pet: 1 <3", hearts) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             if npc == "Any" or npc == "Bachelor": | 
					
						
							|  |  |  |                 possible_friends = [] | 
					
						
							|  |  |  |                 for name in all_villagers_by_name: | 
					
						
							|  |  |  |                     if npc == "Any" or all_villagers_by_name[name].bachelor: | 
					
						
							|  |  |  |                         possible_friends.append(self.has_relationship(name, hearts)) | 
					
						
							|  |  |  |                 return Or(possible_friends) | 
					
						
							|  |  |  |             if npc == "All": | 
					
						
							|  |  |  |                 mandatory_friends = [] | 
					
						
							|  |  |  |                 for name in all_villagers_by_name: | 
					
						
							|  |  |  |                     mandatory_friends.append(self.has_relationship(name, hearts)) | 
					
						
							|  |  |  |                 return And(mandatory_friends) | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |             if npc.isnumeric(): | 
					
						
							|  |  |  |                 possible_friends = [] | 
					
						
							|  |  |  |                 for name in all_villagers_by_name: | 
					
						
							|  |  |  |                     possible_friends.append(self.has_relationship(name, hearts)) | 
					
						
							|  |  |  |                 return Count(int(npc), possible_friends) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             return self.can_earn_relationship(npc, hearts) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         villager = all_villagers_by_name[npc] | 
					
						
							|  |  |  |         if self.options[options.Friendsanity] == options.Friendsanity.option_bachelors and not villager.bachelor: | 
					
						
							|  |  |  |             return self.can_earn_relationship(npc, hearts) | 
					
						
							|  |  |  |         if self.options[options.Friendsanity] == options.Friendsanity.option_starting_npcs and not villager.available: | 
					
						
							|  |  |  |             return self.can_earn_relationship(npc, hearts) | 
					
						
							|  |  |  |         if self.options[ | 
					
						
							|  |  |  |             options.Friendsanity] != options.Friendsanity.option_all_with_marriage and villager.bachelor and hearts > 8: | 
					
						
							|  |  |  |             return self.received(f"{villager.name}: 1 <3", 8) & self.can_earn_relationship(npc, hearts) | 
					
						
							|  |  |  |         return self.received(f"{villager.name}: 1 <3", hearts) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_meet(self, npc: str) -> StardewRule: | 
					
						
							|  |  |  |         if npc not in all_villagers_by_name: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  |         villager = all_villagers_by_name[npc] | 
					
						
							|  |  |  |         rules = [self.can_reach_any_region(villager.locations)] | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |         if npc == "Kent": | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |             rules.append(self.has_lived_months(4)) | 
					
						
							|  |  |  |         if npc == "Dwarf": | 
					
						
							|  |  |  |             rules.append(self.received("Dwarvish Translation Guide")) | 
					
						
							|  |  |  |             rules.append(self.has_tool("Pickaxe", "Iron")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return And(rules) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_earn_relationship(self, npc: str, hearts: int = 0) -> StardewRule: | 
					
						
							|  |  |  |         if npc == "Pet": | 
					
						
							|  |  |  |             return self.can_befriend_pet(hearts) | 
					
						
							|  |  |  |         if npc in all_villagers_by_name: | 
					
						
							|  |  |  |             villager = all_villagers_by_name[npc] | 
					
						
							|  |  |  |             option1 = self.has_season(villager.birthday) & self.has(villager.gifts) & self.has_lived_months(1) | 
					
						
							|  |  |  |             option2 = self.has_season(villager.birthday) & self.has(villager.gifts, 1) & self.has_lived_months( | 
					
						
							|  |  |  |                 hearts // 3) | 
					
						
							|  |  |  |             option3 = (self.has_season(villager.birthday) | self.has(villager.gifts, 1)) & self.has_lived_months( | 
					
						
							|  |  |  |                 hearts // 2) | 
					
						
							|  |  |  |             option4 = self.has_lived_months(hearts) | 
					
						
							|  |  |  |             return self.can_meet(npc) & (option1 | option2 | option3 | option4) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return self.has_lived_months(min(hearts // 2, 8)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_befriend_pet(self, hearts: int): | 
					
						
							|  |  |  |         if hearts == 0: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  |         points = hearts * 200 | 
					
						
							|  |  |  |         points_per_month = 12 * 14 | 
					
						
							|  |  |  |         points_per_water_month = 18 * 14 | 
					
						
							|  |  |  |         return self.can_reach_region(SVRegion.farm) & \ | 
					
						
							|  |  |  |             ((self.has_tool("Watering Can") & self.has_lived_months(points // points_per_water_month)) | | 
					
						
							|  |  |  |              self.has_lived_months(points // points_per_month)) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def can_complete_bundle(self, bundle_requirements: List[BundleItem], number_required: int) -> StardewRule: | 
					
						
							|  |  |  |         item_rules = [] | 
					
						
							|  |  |  |         for bundle_item in bundle_requirements: | 
					
						
							|  |  |  |             if bundle_item.item.item_id == -1: | 
					
						
							|  |  |  |                 return self.can_spend_money(bundle_item.amount) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 item_rules.append(bundle_item.item.name) | 
					
						
							|  |  |  |         return self.has(item_rules, number_required) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_complete_community_center(self) -> StardewRule: | 
					
						
							|  |  |  |         return (self.can_reach_location("Complete Crafts Room") & | 
					
						
							|  |  |  |                 self.can_reach_location("Complete Pantry") & | 
					
						
							|  |  |  |                 self.can_reach_location("Complete Fish Tank") & | 
					
						
							|  |  |  |                 self.can_reach_location("Complete Bulletin Board") & | 
					
						
							|  |  |  |                 self.can_reach_location("Complete Vault") & | 
					
						
							|  |  |  |                 self.can_reach_location("Complete Boiler Room")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_finish_grandpa_evaluation(self) -> StardewRule: | 
					
						
							|  |  |  |         # https://stardewvalleywiki.com/Grandpa | 
					
						
							|  |  |  |         rules_worth_a_point = [self.can_have_earned_total_money(50000),  # 50 000g | 
					
						
							|  |  |  |                                self.can_have_earned_total_money(100000),  # 100 000g | 
					
						
							|  |  |  |                                self.can_have_earned_total_money(200000),  # 200 000g | 
					
						
							|  |  |  |                                self.can_have_earned_total_money(300000),  # 300 000g | 
					
						
							|  |  |  |                                self.can_have_earned_total_money(500000),  # 500 000g | 
					
						
							|  |  |  |                                self.can_have_earned_total_money(1000000),  # 1 000 000g first point | 
					
						
							|  |  |  |                                self.can_have_earned_total_money(1000000),  # 1 000 000g second point | 
					
						
							|  |  |  |                                self.has_total_skill_level(30),  # Total Skills: 30 | 
					
						
							|  |  |  |                                self.has_total_skill_level(50),  # Total Skills: 50 | 
					
						
							|  |  |  |                                # Completing the museum not expected | 
					
						
							|  |  |  |                                # Catching every fish not expected | 
					
						
							|  |  |  |                                # Shipping every item not expected | 
					
						
							|  |  |  |                                self.can_get_married() & self.has_house(2), | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |                                self.has_relationship("5", 8),  # 5 Friends | 
					
						
							|  |  |  |                                self.has_relationship("10", 8),  # 10 friends | 
					
						
							|  |  |  |                                self.has_relationship("Pet", 5),  # Max Pet | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                                self.can_complete_community_center(),  # Community Center Completion | 
					
						
							|  |  |  |                                self.can_complete_community_center(),  # CC Ceremony first point | 
					
						
							|  |  |  |                                self.can_complete_community_center(),  # CC Ceremony second point | 
					
						
							|  |  |  |                                self.received("Skull Key"),  # Skull Key obtained | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |                                self.has_rusty_key(),  # Rusty key not expected | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  |                                ] | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         return Count(12, rules_worth_a_point) | 
					
						
							| 
									
										
										
										
											2023-02-26 19:19:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_any_weapon(self) -> StardewRule: | 
					
						
							|  |  |  |         return self.has_decent_weapon() | self.received(item.name for item in all_items if Group.WEAPON in item.groups) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_decent_weapon(self) -> StardewRule: | 
					
						
							|  |  |  |         return (self.has_good_weapon() | | 
					
						
							|  |  |  |                 self.received(item.name for item in all_items | 
					
						
							|  |  |  |                               if Group.WEAPON in item.groups and | 
					
						
							|  |  |  |                               (Group.MINES_FLOOR_50 in item.groups or Group.MINES_FLOOR_60 in item.groups))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_good_weapon(self) -> StardewRule: | 
					
						
							|  |  |  |         return ((self.has_great_weapon() | | 
					
						
							|  |  |  |                  self.received(item.name for item in all_items | 
					
						
							|  |  |  |                                if Group.WEAPON in item.groups and | 
					
						
							|  |  |  |                                (Group.MINES_FLOOR_80 in item.groups or Group.MINES_FLOOR_90 in item.groups))) & | 
					
						
							|  |  |  |                 self.received("Adventurer's Guild")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_great_weapon(self) -> StardewRule: | 
					
						
							|  |  |  |         return ((self.has_galaxy_weapon() | | 
					
						
							|  |  |  |                  self.received(item.name for item in all_items | 
					
						
							|  |  |  |                                if Group.WEAPON in item.groups and Group.MINES_FLOOR_110 in item.groups)) & | 
					
						
							|  |  |  |                 self.received("Adventurer's Guild")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_galaxy_weapon(self) -> StardewRule: | 
					
						
							|  |  |  |         return (self.received(item.name for item in all_items | 
					
						
							|  |  |  |                               if Group.WEAPON in item.groups and Group.GALAXY_WEAPONS in item.groups) & | 
					
						
							|  |  |  |                 self.received("Adventurer's Guild")) | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_year_two(self) -> StardewRule: | 
					
						
							|  |  |  |         return self.has_lived_months(4) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_spring_summer_or_fall(self) -> StardewRule: | 
					
						
							|  |  |  |         return self.has_season("Spring") | self.has_season("Summer") | self.has_season("Fall") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_find_museum_item(self, item: MuseumItem) -> StardewRule: | 
					
						
							|  |  |  |         region_rule = self.can_reach_all_regions(item.locations) | 
					
						
							|  |  |  |         geodes_rule = self.has(item.geodes) | 
					
						
							|  |  |  |         # monster_rule = self.can_farm_monster(item.monsters) | 
					
						
							|  |  |  |         # extra_rule = True_() | 
					
						
							|  |  |  |         return region_rule & geodes_rule  # & monster_rule & extra_rule | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def can_complete_museum(self) -> StardewRule: | 
					
						
							| 
									
										
										
										
											2023-04-14 23:42:02 -04:00
										 |  |  |         rules = [self.can_mine_perfectly_in_the_skull_cavern()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.options[options.Museumsanity] != options.Museumsanity.option_none: | 
					
						
							|  |  |  |             rules.append(self.received("Traveling Merchant Metal Detector", 4)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 19:44:59 -04:00
										 |  |  |         for donation in all_museum_items: | 
					
						
							|  |  |  |             rules.append(self.can_find_museum_item(donation)) | 
					
						
							|  |  |  |         return And(rules) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_season(self, season: str) -> StardewRule: | 
					
						
							|  |  |  |         seasons_order = ["Spring", "Summer", "Fall", "Winter"] | 
					
						
							|  |  |  |         if self.options[options.SeasonRandomization] == options.SeasonRandomization.option_progressive: | 
					
						
							|  |  |  |             return self.received("Progressive Season", seasons_order.index(season)) | 
					
						
							|  |  |  |         if self.options[options.SeasonRandomization] == options.SeasonRandomization.option_disabled: | 
					
						
							|  |  |  |             if season == "Spring": | 
					
						
							|  |  |  |                 return True_() | 
					
						
							|  |  |  |             return self.has_lived_months(1) | 
					
						
							|  |  |  |         return self.received(season) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_any_season(self, seasons: Iterable[str]): | 
					
						
							|  |  |  |         if not seasons: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  |         return Or([self.has_season(season) for season in seasons]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_all_seasons(self, seasons: Iterable[str]): | 
					
						
							|  |  |  |         if not seasons: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  |         return And([self.has_season(season) for season in seasons]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_lived_months(self, number: int) -> StardewRule: | 
					
						
							|  |  |  |         number = max(0, min(number, 8)) | 
					
						
							|  |  |  |         return self.received("Month End", number) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_rusty_key(self) -> StardewRule: | 
					
						
							|  |  |  |         if self.options[options.Museumsanity] == options.Museumsanity.option_none: | 
					
						
							|  |  |  |             return True_() | 
					
						
							|  |  |  |         return self.received("Rusty Key") |