More files, actually

This commit is contained in:
object-Object 2023-06-20 00:56:26 -04:00
parent 99e1e899b9
commit 5baecea2fd
4 changed files with 215 additions and 209 deletions

View file

@ -1,2 +1,44 @@
from common.deserialize import TypeHooks
from common.tagged_union import get_union_types
from .abstract import *
from .concrete import *
from .hexcasting import *
from .patchouli import *
Page = (
TextPage
| ImagePage
| CraftingPage
| SmeltingPage
| MultiblockPage
| EntityPage
| SpotlightPage
| LinkPage
| RelationsPage
| QuestPage
| EmptyPage
| PatternPage
| ManualPatternNosigPage
| ManualOpPatternPage
| ManualRawPatternPage
| CraftingMultiPage
| BrainsweepPage
)
def _raw_page_hook(data: dict[str, Any] | str) -> dict[str, Any]:
if isinstance(data, str):
# special case, thanks patchouli
return {"type": "patchouli:text", "text": data}
return data
def make_page_hooks(book: Book) -> TypeHooks:
"""Creates type hooks for deserializing Page types."""
type_hooks: TypeHooks = {Page: _raw_page_hook}
for cls_ in get_union_types(Page):
type_hooks[cls_] = cls_.make_type_hook(book)
return type_hooks

View file

@ -1,208 +0,0 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
from common.deserialize import TypeHooks, rename
from common.formatting import FormatTree
from common.pattern import RawPatternInfo
from common.tagged_union import get_union_types
from common.types import Book, LocalizedItem, LocalizedStr
from minecraft.recipe import BrainsweepRecipe, CraftingRecipe
from minecraft.resource import Entity, ItemStack, ResourceLocation
from .abstract import (
BasePage,
PageWithCraftingRecipes,
PageWithPattern,
PageWithText,
PageWithTitle,
)
@dataclass(kw_only=True)
class TextPage(PageWithTitle, type="patchouli:text"):
text: FormatTree
@dataclass
class ImagePage(PageWithTitle, type="patchouli:image"):
images: list[ResourceLocation]
border: bool = False
@dataclass
class CraftingPage(PageWithCraftingRecipes, type="patchouli:crafting"):
recipe: CraftingRecipe
recipe2: CraftingRecipe | None = None
@property
def recipes(self) -> list[CraftingRecipe]:
recipes = [self.recipe]
if self.recipe2:
recipes.append(self.recipe2)
return recipes
# TODO: this should probably inherit PageWithRecipes too
@dataclass
class SmeltingPage(PageWithTitle, type="patchouli:smelting"):
recipe: ItemStack
recipe2: ItemStack | None = None
@dataclass
class MultiblockPage(PageWithText, type="patchouli:multiblock"):
name: LocalizedStr
multiblock_id: ResourceLocation | None = None
# TODO: https://vazkiimods.github.io/Patchouli/docs/patchouli-basics/multiblocks/
# this should be a dataclass, but hex doesn't have any multiblock pages so idc
multiblock: Any | None = None
enable_visualize: bool = True
def __post_init__(self):
if self.multiblock_id is None and self.multiblock is None:
raise ValueError(f"One of multiblock_id or multiblock must be set\n{self}")
@dataclass
class EntityPage(PageWithText, type="patchouli:entity"):
entity: Entity
scale: float = 1
offset: float = 0
rotate: bool = True
default_rotation: float = -45
name: LocalizedStr | None = None
@dataclass
class SpotlightPage(PageWithTitle, type="patchouli:spotlight"):
item: LocalizedItem # TODO: patchi says this is an ItemStack, so this might break
link_recipe: bool = False
@dataclass
class LinkPage(TextPage, type="patchouli:link"):
url: str
link_text: LocalizedStr
@dataclass(kw_only=True)
class RelationsPage(PageWithTitle, type="patchouli:relations"):
entries: list[ResourceLocation]
_title: LocalizedStr = field(
default=LocalizedStr("Related Chapters"), metadata=rename("title")
)
@dataclass
class QuestPage(PageWithTitle, type="patchouli:quest"):
trigger: ResourceLocation | None = None
_title: LocalizedStr = field(
default=LocalizedStr("Objective"), metadata=rename("title")
)
@dataclass
class EmptyPage(BasePage, type="patchouli:empty"):
draw_filler: bool = True
@dataclass
class PatternPage(PageWithPattern, type="hexcasting:pattern"):
patterns: list[RawPatternInfo] = field(init=False)
op_id: ResourceLocation
header: None
def __post_init__(self):
self.patterns = [self.book.patterns[self.op_id]]
@property
def name(self) -> LocalizedStr:
return self.i18n.localize_pattern(self.op_id)
@dataclass
class ManualPatternNosigPage(PageWithPattern, type="hexcasting:manual_pattern_nosig"):
header: LocalizedStr
op_id: None
input: None
output: None
@property
def name(self) -> LocalizedStr:
return self.header
@dataclass
class ManualOpPatternPage(PageWithPattern, type="hexcasting:manual_pattern"):
op_id: ResourceLocation
header: None
@property
def name(self) -> LocalizedStr:
return self.i18n.localize_pattern(self.op_id)
@dataclass
class ManualRawPatternPage(PageWithPattern, type="hexcasting:manual_pattern"):
op_id: None
header: LocalizedStr
@property
def name(self) -> LocalizedStr:
return self.header
@dataclass
class CraftingMultiPage(PageWithCraftingRecipes, type="hexcasting:crafting_multi"):
heading: LocalizedStr # ...heading?
_recipes: list[CraftingRecipe] = field(metadata=rename("recipes"))
@property
def recipes(self) -> list[CraftingRecipe]:
return self._recipes
@dataclass
class BrainsweepPage(PageWithText, type="hexcasting:brainsweep"):
recipe: BrainsweepRecipe
Page = (
TextPage
| ImagePage
| CraftingPage
| SmeltingPage
| MultiblockPage
| EntityPage
| SpotlightPage
| LinkPage
| RelationsPage
| QuestPage
| EmptyPage
| PatternPage
| ManualPatternNosigPage
| ManualOpPatternPage
| ManualRawPatternPage
| CraftingMultiPage
| BrainsweepPage
)
def _raw_page_hook(data: dict[str, Any] | str) -> dict[str, Any]:
if isinstance(data, str):
# special case, thanks patchouli
return {"type": "patchouli:text", "text": data}
return data
def make_page_hooks(book: Book) -> TypeHooks:
"""Creates type hooks for deserializing Page types."""
type_hooks: TypeHooks = {Page: _raw_page_hook}
for cls_ in get_union_types(Page):
type_hooks[cls_] = cls_.make_type_hook(book)
return type_hooks

View file

@ -0,0 +1,72 @@
from __future__ import annotations
from dataclasses import dataclass, field
from common.deserialize import rename
from common.pattern import RawPatternInfo
from common.types import LocalizedStr
from minecraft.recipe import BrainsweepRecipe, CraftingRecipe
from minecraft.resource import ResourceLocation
from .abstract import PageWithCraftingRecipes, PageWithPattern, PageWithText
@dataclass
class PatternPage(PageWithPattern, type="hexcasting:pattern"):
patterns: list[RawPatternInfo] = field(init=False)
op_id: ResourceLocation
header: None
def __post_init__(self):
self.patterns = [self.book.patterns[self.op_id]]
@property
def name(self) -> LocalizedStr:
return self.i18n.localize_pattern(self.op_id)
@dataclass
class ManualPatternNosigPage(PageWithPattern, type="hexcasting:manual_pattern_nosig"):
header: LocalizedStr
op_id: None
input: None
output: None
@property
def name(self) -> LocalizedStr:
return self.header
@dataclass
class ManualOpPatternPage(PageWithPattern, type="hexcasting:manual_pattern"):
op_id: ResourceLocation
header: None
@property
def name(self) -> LocalizedStr:
return self.i18n.localize_pattern(self.op_id)
@dataclass
class ManualRawPatternPage(PageWithPattern, type="hexcasting:manual_pattern"):
op_id: None
header: LocalizedStr
@property
def name(self) -> LocalizedStr:
return self.header
@dataclass
class CraftingMultiPage(PageWithCraftingRecipes, type="hexcasting:crafting_multi"):
heading: LocalizedStr # ...heading?
_recipes: list[CraftingRecipe] = field(metadata=rename("recipes"))
@property
def recipes(self) -> list[CraftingRecipe]:
return self._recipes
@dataclass
class BrainsweepPage(PageWithText, type="hexcasting:brainsweep"):
recipe: BrainsweepRecipe

View file

@ -0,0 +1,100 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
from common.deserialize import rename
from common.formatting import FormatTree
from common.types import LocalizedItem, LocalizedStr
from minecraft.recipe import CraftingRecipe
from minecraft.resource import Entity, ItemStack, ResourceLocation
from .abstract import BasePage, PageWithCraftingRecipes, PageWithText, PageWithTitle
@dataclass(kw_only=True)
class TextPage(PageWithTitle, type="patchouli:text"):
text: FormatTree
@dataclass
class ImagePage(PageWithTitle, type="patchouli:image"):
images: list[ResourceLocation]
border: bool = False
@dataclass
class CraftingPage(PageWithCraftingRecipes, type="patchouli:crafting"):
recipe: CraftingRecipe
recipe2: CraftingRecipe | None = None
@property
def recipes(self) -> list[CraftingRecipe]:
recipes = [self.recipe]
if self.recipe2:
recipes.append(self.recipe2)
return recipes
# TODO: this should probably inherit PageWithRecipes too
@dataclass
class SmeltingPage(PageWithTitle, type="patchouli:smelting"):
recipe: ItemStack
recipe2: ItemStack | None = None
@dataclass
class MultiblockPage(PageWithText, type="patchouli:multiblock"):
name: LocalizedStr
multiblock_id: ResourceLocation | None = None
# TODO: https://vazkiimods.github.io/Patchouli/docs/patchouli-basics/multiblocks/
# this should be a dataclass, but hex doesn't have any multiblock pages so idc
multiblock: Any | None = None
enable_visualize: bool = True
def __post_init__(self):
if self.multiblock_id is None and self.multiblock is None:
raise ValueError(f"One of multiblock_id or multiblock must be set\n{self}")
@dataclass
class EntityPage(PageWithText, type="patchouli:entity"):
entity: Entity
scale: float = 1
offset: float = 0
rotate: bool = True
default_rotation: float = -45
name: LocalizedStr | None = None
@dataclass
class SpotlightPage(PageWithTitle, type="patchouli:spotlight"):
item: LocalizedItem # TODO: patchi says this is an ItemStack, so this might break
link_recipe: bool = False
@dataclass
class LinkPage(TextPage, type="patchouli:link"):
url: str
link_text: LocalizedStr
@dataclass(kw_only=True)
class RelationsPage(PageWithTitle, type="patchouli:relations"):
entries: list[ResourceLocation]
_title: LocalizedStr = field(
default=LocalizedStr("Related Chapters"), metadata=rename("title")
)
@dataclass
class QuestPage(PageWithTitle, type="patchouli:quest"):
trigger: ResourceLocation | None = None
_title: LocalizedStr = field(
default=LocalizedStr("Objective"), metadata=rename("title")
)
@dataclass
class EmptyPage(BasePage, type="patchouli:empty"):
draw_filler: bool = True