141 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
	
| from dataclasses import dataclass
 | |
| from typing import Iterable, Union, List, Tuple, Hashable
 | |
| 
 | |
| from BaseClasses import ItemClassification, CollectionState
 | |
| from .base import BaseStardewRule, CombinableStardewRule
 | |
| from .protocol import StardewRule
 | |
| from ..items import item_table
 | |
| 
 | |
| 
 | |
| 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]
 | |
| 
 | |
|         assert items_list, "Can't create a Total Received conditions without items"
 | |
|         for item in items_list:
 | |
|             assert item_table[item].classification & ItemClassification.progression, \
 | |
|                 f"Item [{item_table[item].name}] has to be progression to be used in logic"
 | |
| 
 | |
|         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 get_difficulty(self):
 | |
|         return self.count
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return f"Received {self.count} {self.items}"
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True)
 | |
| class Received(CombinableStardewRule):
 | |
|     item: str
 | |
|     player: int
 | |
|     count: int
 | |
| 
 | |
|     def __post_init__(self):
 | |
|         assert item_table[self.item].classification & ItemClassification.progression, \
 | |
|             f"Item [{item_table[self.item].name}] has to be progression to be used in logic"
 | |
| 
 | |
|     @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 {self.item}"
 | |
|         return f"Received {self.count} {self.item}"
 | |
| 
 | |
|     def get_difficulty(self):
 | |
|         return self.count
 | |
| 
 | |
| 
 | |
| @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}"
 | |
| 
 | |
|     def get_difficulty(self):
 | |
|         return 1
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True)
 | |
| class HasProgressionPercent(CombinableStardewRule):
 | |
|     player: int
 | |
|     percent: int
 | |
| 
 | |
|     def __post_init__(self):
 | |
|         assert self.percent > 0, "HasProgressionPercent rule must be above 0%"
 | |
|         assert self.percent <= 100, "HasProgressionPercent rule can't require more than 100% of items"
 | |
| 
 | |
|     @property
 | |
|     def combination_key(self) -> Hashable:
 | |
|         return HasProgressionPercent.__name__
 | |
| 
 | |
|     @property
 | |
|     def value(self):
 | |
|         return self.percent
 | |
| 
 | |
|     def __call__(self, state: CollectionState) -> bool:
 | |
|         stardew_world = state.multiworld.worlds[self.player]
 | |
|         total_count = stardew_world.total_progression_items
 | |
|         needed_count = (total_count * self.percent) // 100
 | |
|         total_count = 0
 | |
|         for item in state.prog_items[self.player]:
 | |
|             item_count = state.prog_items[self.player][item]
 | |
|             total_count += item_count
 | |
|             if total_count >= needed_count:
 | |
|                 return True
 | |
|         return False
 | |
| 
 | |
|     def evaluate_while_simplifying(self, state: CollectionState) -> Tuple[StardewRule, bool]:
 | |
|         return self, self(state)
 | |
| 
 | |
|     def __repr__(self):
 | |
|         return f"HasProgressionPercent {self.percent}"
 | |
| 
 | |
|     def get_difficulty(self):
 | |
|         return self.percent
 |