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"
|