101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from dataclasses import dataclass
 | |
| from typing import Iterable, Union, List, Tuple, Hashable, TYPE_CHECKING
 | |
| 
 | |
| from BaseClasses import CollectionState
 | |
| from .base import BaseStardewRule, CombinableStardewRule
 | |
| from .protocol import StardewRule
 | |
| from ..strings.ap_names.event_names import Event
 | |
| 
 | |
| if TYPE_CHECKING:
 | |
|     from .. import StardewValleyWorld
 | |
| 
 | |
| 
 | |
| class TotalReceived(BaseStardewRule):
 | |
|     count: int
 | |
|     items: Iterable[str]
 | |
|     player: int
 | |
| 
 | |
|     def __init__(self, count: int, items: Union[str, Iterable[str]], player: int):
 | |
|         items_list: List[str]
 | |
| 
 | |
|         if isinstance(items, Iterable):
 | |
|             items_list = [*items]
 | |
|         else:
 | |
|             items_list = [items]
 | |
| 
 | |
|         self.player = player
 | |
|         self.items = items_list
 | |
|         self.count = count
 | |
| 
 | |
|     def __call__(self, state: CollectionState) -> bool:
 | |
|         c = 0
 | |
|         for item in self.items:
 | |
|             c += state.count(item, self.player)
 | |
|             if c >= self.count:
 | |
|                 return True
 | |
|         return False
 | |
| 
 | |
|     def evaluate_while_simplifying(self, state: CollectionState) -> Tuple[StardewRule, bool]:
 | |
|         return self, self(state)
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return f"Received {self.count} {self.items}"
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True)
 | |
| class Received(CombinableStardewRule):
 | |
|     item: str
 | |
|     player: int
 | |
|     count: int
 | |
|     event: bool = False
 | |
|     """Helps `explain` to know it can dig into a location with the same name."""
 | |
| 
 | |
|     @property
 | |
|     def combination_key(self) -> Hashable:
 | |
|         return self.item
 | |
| 
 | |
|     @property
 | |
|     def value(self):
 | |
|         return self.count
 | |
| 
 | |
|     def __call__(self, state: CollectionState) -> bool:
 | |
|         return state.has(self.item, self.player, self.count)
 | |
| 
 | |
|     def evaluate_while_simplifying(self, state: CollectionState) -> Tuple[StardewRule, bool]:
 | |
|         return self, self(state)
 | |
| 
 | |
|     def __repr__(self):
 | |
|         if self.count == 1:
 | |
|             return f"Received {'event ' if self.event else ''}{self.item}"
 | |
|         return f"Received {'event ' if self.event else ''}{self.count} {self.item}"
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True)
 | |
| class Reach(BaseStardewRule):
 | |
|     spot: str
 | |
|     resolution_hint: str
 | |
|     player: int
 | |
| 
 | |
|     def __call__(self, state: CollectionState) -> bool:
 | |
|         if self.resolution_hint == 'Region' and self.spot not in state.multiworld.regions.region_cache[self.player]:
 | |
|             return False
 | |
|         return state.can_reach(self.spot, self.resolution_hint, self.player)
 | |
| 
 | |
|     def evaluate_while_simplifying(self, state: CollectionState) -> Tuple[StardewRule, bool]:
 | |
|         return self, self(state)
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return f"Reach {self.resolution_hint} {self.spot}"
 | |
| 
 | |
| 
 | |
| class HasProgressionPercent(Received):
 | |
|     def __init__(self, player: int, percent: int):
 | |
|         super().__init__(Event.received_progression_percent, player, percent, event=True)
 | |
| 
 | |
|     def __post_init__(self):
 | |
|         assert self.count > 0, "HasProgressionPercent rule must be above 0%"
 | |
|         assert self.count <= 100, "HasProgressionPercent rule can't require more than 100% of items"
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return f"Received {self.count}% progression items"
 | 
