mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
146 lines
4.4 KiB
Python
146 lines
4.4 KiB
Python
import csv
|
|
import enum
|
|
from dataclasses import dataclass, field
|
|
from functools import reduce
|
|
from pathlib import Path
|
|
from typing import Dict, List, Protocol, Union, Set, Optional
|
|
|
|
from BaseClasses import Item, ItemClassification
|
|
from .. import data
|
|
from ..logic.logic_event import all_events
|
|
|
|
ITEM_CODE_OFFSET = 717000
|
|
|
|
world_folder = Path(__file__).parent
|
|
|
|
|
|
class Group(enum.Enum):
|
|
RESOURCE_PACK = enum.auto()
|
|
FRIENDSHIP_PACK = enum.auto()
|
|
COMMUNITY_REWARD = enum.auto()
|
|
TRASH = enum.auto()
|
|
FOOTWEAR = enum.auto()
|
|
HATS = enum.auto()
|
|
RING = enum.auto()
|
|
WEAPON = enum.auto()
|
|
WEAPON_GENERIC = enum.auto()
|
|
WEAPON_SWORD = enum.auto()
|
|
WEAPON_CLUB = enum.auto()
|
|
WEAPON_DAGGER = enum.auto()
|
|
WEAPON_SLINGSHOT = enum.auto()
|
|
PROGRESSIVE_TOOLS = enum.auto()
|
|
SKILL_LEVEL_UP = enum.auto()
|
|
SKILL_MASTERY = enum.auto()
|
|
BUILDING = enum.auto()
|
|
WIZARD_BUILDING = enum.auto()
|
|
DESERT_TRANSPORTATION = enum.auto()
|
|
ISLAND_TRANSPORTATION = enum.auto()
|
|
ARCADE_MACHINE_BUFFS = enum.auto()
|
|
BASE_RESOURCE = enum.auto()
|
|
WARP_TOTEM = enum.auto()
|
|
GEODE = enum.auto()
|
|
ORE = enum.auto()
|
|
FERTILIZER = enum.auto()
|
|
SEED = enum.auto()
|
|
CROPSANITY = enum.auto()
|
|
FISHING_RESOURCE = enum.auto()
|
|
SEASON = enum.auto()
|
|
TRAVELING_MERCHANT_DAY = enum.auto()
|
|
MUSEUM = enum.auto()
|
|
FRIENDSANITY = enum.auto()
|
|
FESTIVAL = enum.auto()
|
|
RARECROW = enum.auto()
|
|
TRAP = enum.auto()
|
|
BONUS = enum.auto()
|
|
MAXIMUM_ONE = enum.auto()
|
|
AT_LEAST_TWO = enum.auto()
|
|
DEPRECATED = enum.auto()
|
|
RESOURCE_PACK_USEFUL = enum.auto()
|
|
SPECIAL_ORDER_BOARD = enum.auto()
|
|
SPECIAL_ORDER_QI = enum.auto()
|
|
BABY = enum.auto()
|
|
GINGER_ISLAND = enum.auto()
|
|
WALNUT_PURCHASE = enum.auto()
|
|
TV_CHANNEL = enum.auto()
|
|
QI_CRAFTING_RECIPE = enum.auto()
|
|
CHEFSANITY = enum.auto()
|
|
CHEFSANITY_STARTER = enum.auto()
|
|
CHEFSANITY_QOS = enum.auto()
|
|
CHEFSANITY_PURCHASE = enum.auto()
|
|
CHEFSANITY_FRIENDSHIP = enum.auto()
|
|
CHEFSANITY_SKILL = enum.auto()
|
|
CRAFTSANITY = enum.auto()
|
|
BOOK_POWER = enum.auto()
|
|
LOST_BOOK = enum.auto()
|
|
PLAYER_BUFF = enum.auto()
|
|
# Mods
|
|
MAGIC_SPELL = enum.auto()
|
|
MOD_WARP = enum.auto()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ItemData:
|
|
code_without_offset: Optional[int]
|
|
name: str
|
|
classification: ItemClassification
|
|
mod_name: Optional[str] = None
|
|
groups: Set[Group] = field(default_factory=frozenset)
|
|
|
|
def __post_init__(self):
|
|
if not isinstance(self.groups, frozenset):
|
|
super().__setattr__("groups", frozenset(self.groups))
|
|
|
|
@property
|
|
def code(self):
|
|
return ITEM_CODE_OFFSET + self.code_without_offset if self.code_without_offset is not None else None
|
|
|
|
def has_any_group(self, *group: Group) -> bool:
|
|
groups = set(group)
|
|
return bool(groups.intersection(self.groups))
|
|
|
|
|
|
class StardewItemFactory(Protocol):
|
|
def __call__(self, name: Union[str, ItemData], override_classification: ItemClassification = None) -> Item:
|
|
raise NotImplementedError
|
|
|
|
|
|
def load_item_csv():
|
|
from importlib.resources import files
|
|
|
|
items = []
|
|
with files(data).joinpath("items.csv").open() as file:
|
|
item_reader = csv.DictReader(file)
|
|
for item in item_reader:
|
|
id = int(item["id"]) if item["id"] else None
|
|
classification = reduce((lambda a, b: a | b), {ItemClassification[str_classification] for str_classification in item["classification"].split(",")})
|
|
groups = {Group[group] for group in item["groups"].split(",") if group}
|
|
mod_name = str(item["mod_name"]) if item["mod_name"] else None
|
|
items.append(ItemData(id, item["name"], classification, mod_name, groups))
|
|
return items
|
|
|
|
|
|
events = [
|
|
ItemData(None, e, ItemClassification.progression)
|
|
for e in sorted(all_events)
|
|
]
|
|
|
|
all_items: List[ItemData] = load_item_csv() + events
|
|
item_table: Dict[str, ItemData] = {}
|
|
items_by_group: Dict[Group, List[ItemData]] = {}
|
|
|
|
|
|
def initialize_groups():
|
|
for item in all_items:
|
|
for group in item.groups:
|
|
item_group = items_by_group.get(group, list())
|
|
item_group.append(item)
|
|
items_by_group[group] = item_group
|
|
|
|
|
|
def initialize_item_table():
|
|
item_table.update({item.name: item for item in all_items})
|
|
|
|
|
|
initialize_item_table()
|
|
initialize_groups()
|