87 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			87 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import enum | ||
|  | import sys | ||
|  | from abc import ABC | ||
|  | from dataclasses import dataclass, field | ||
|  | from types import MappingProxyType | ||
|  | from typing import List, Iterable, Set, ClassVar, Tuple, Mapping, Callable, Any | ||
|  | 
 | ||
|  | from ..stardew_rule.protocol import StardewRule | ||
|  | 
 | ||
|  | if sys.version_info >= (3, 10): | ||
|  |     kw_only = {"kw_only": True} | ||
|  | else: | ||
|  |     kw_only = {} | ||
|  | 
 | ||
|  | DEFAULT_REQUIREMENT_TAGS = MappingProxyType({}) | ||
|  | 
 | ||
|  | 
 | ||
|  | @dataclass(frozen=True) | ||
|  | class Requirement(ABC): | ||
|  |     ... | ||
|  | 
 | ||
|  | 
 | ||
|  | class ItemTag(enum.Enum): | ||
|  |     CROPSANITY_SEED = enum.auto() | ||
|  |     CROPSANITY = enum.auto() | ||
|  |     FISH = enum.auto() | ||
|  |     FRUIT = enum.auto() | ||
|  |     VEGETABLE = enum.auto() | ||
|  |     EDIBLE_MUSHROOM = enum.auto() | ||
|  |     BOOK = enum.auto() | ||
|  |     BOOK_POWER = enum.auto() | ||
|  |     BOOK_SKILL = enum.auto() | ||
|  | 
 | ||
|  | 
 | ||
|  | @dataclass(frozen=True) | ||
|  | class ItemSource(ABC): | ||
|  |     add_tags: ClassVar[Tuple[ItemTag]] = () | ||
|  | 
 | ||
|  |     @property | ||
|  |     def requirement_tags(self) -> Mapping[str, Tuple[ItemTag, ...]]: | ||
|  |         return DEFAULT_REQUIREMENT_TAGS | ||
|  | 
 | ||
|  |     # FIXME this should just be an optional field, but kw_only requires python 3.10... | ||
|  |     @property | ||
|  |     def other_requirements(self) -> Iterable[Requirement]: | ||
|  |         return () | ||
|  | 
 | ||
|  | 
 | ||
|  | @dataclass(frozen=True, **kw_only) | ||
|  | class GenericSource(ItemSource): | ||
|  |     regions: Tuple[str, ...] = () | ||
|  |     """No region means it's available everywhere.""" | ||
|  |     other_requirements: Tuple[Requirement, ...] = () | ||
|  | 
 | ||
|  | 
 | ||
|  | @dataclass(frozen=True) | ||
|  | class CustomRuleSource(ItemSource): | ||
|  |     """Hopefully once everything is migrated to sources, we won't need these custom logic anymore.""" | ||
|  |     create_rule: Callable[[Any], StardewRule] | ||
|  | 
 | ||
|  | 
 | ||
|  | class Tag(ItemSource): | ||
|  |     """Not a real source, just a way to add tags to an item. Will be removed from the item sources during unpacking.""" | ||
|  |     tag: Tuple[ItemTag, ...] | ||
|  | 
 | ||
|  |     def __init__(self, *tag: ItemTag): | ||
|  |         self.tag = tag  # noqa | ||
|  | 
 | ||
|  |     @property | ||
|  |     def add_tags(self): | ||
|  |         return self.tag | ||
|  | 
 | ||
|  | 
 | ||
|  | @dataclass(frozen=True) | ||
|  | class GameItem: | ||
|  |     name: str | ||
|  |     sources: List[ItemSource] = field(default_factory=list) | ||
|  |     tags: Set[ItemTag] = field(default_factory=set) | ||
|  | 
 | ||
|  |     def add_sources(self, sources: Iterable[ItemSource]): | ||
|  |         self.sources.extend(source for source in sources if type(source) is not Tag) | ||
|  |         for source in sources: | ||
|  |             self.add_tags(source.add_tags) | ||
|  | 
 | ||
|  |     def add_tags(self, tags: Iterable[ItemTag]): | ||
|  |         self.tags.update(tags) |