Skip to content

Commit f8c3534

Browse files
committed
Add support for Fabric resource conditions
1 parent 7bf3080 commit f8c3534

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Pydantic's HISTORY.md](https://github.com/pydantic/pydantic/blob/main/HISTORY.md), and this project *mostly* adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [UNRELEASED]
8+
9+
### Fixed
10+
11+
* Fixed a validation failure when using [Fabric Resource Conditions](https://github.com/FabricMC/fabric/blob/761f669d0a6fbfe2ae6d71d767651f32a13d37fc/fabric-resource-conditions-api-v1/src/main/java/net/fabricmc/fabric/api/resource/conditions/v1/ResourceConditions.java#L64).
12+
713
## `1!0.1.0a31`
814

915
### Added

src/hexdoc/minecraft/recipe/recipes.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import ClassVar, Iterator, Unpack
1+
from typing import Any, ClassVar, Iterator, Unpack
22

33
from pydantic import ConfigDict, Field, PrivateAttr, ValidationInfo, model_validator
44
from typing_extensions import override
@@ -29,6 +29,14 @@ class Recipe(TypeTaggedTemplate, ResourceModel):
2929
default_factory=ValueIfVersion(">=1.20", True, None)
3030
)
3131

32+
fabric_load_conditions: list[dict[str, Any]] | None = Field(
33+
default=None, alias="fabric:load_conditions"
34+
)
35+
"""Fabric resource conditions.
36+
37+
https://github.com/FabricMC/fabric/blob/761f669d0a6fbfe2ae6d71d767651f32a13d37fc/fabric-resource-conditions-api-v1/src/main/java/net/fabricmc/fabric/api/resource/conditions/v1/ResourceConditions.java#L64
38+
"""
39+
3240
# not in the actual model
3341

3442
_workstation: ClassVar[ResourceLocation | None] = None
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from collections import defaultdict
2+
from contextlib import ExitStack
3+
from pathlib import Path
4+
from typing import Any
5+
6+
import pytest
7+
from hexdoc.core.loader import ModResourceLoader
8+
from hexdoc.core.properties import LangProps, Properties
9+
from hexdoc.core.resource import ResourceLocation
10+
from hexdoc.core.resource_dir import PathResourceDir
11+
from hexdoc.minecraft.assets.textures import TextureContext
12+
from hexdoc.minecraft.i18n import I18n
13+
from hexdoc.minecraft.recipe.recipes import CraftingShapelessRecipe, Recipe
14+
from hexdoc.plugin.manager import PluginManager
15+
from hexdoc.utils.context import ContextSource
16+
from pydantic import TypeAdapter
17+
18+
19+
@pytest.fixture
20+
def context():
21+
props = Properties.model_construct()
22+
23+
pm = PluginManager("branch", props=props)
24+
25+
loader = ModResourceLoader(
26+
props=props,
27+
export_dir=None,
28+
resource_dirs=[],
29+
_stack=ExitStack(),
30+
)
31+
32+
i18n = I18n(
33+
lookup=I18n.parse_lookup(
34+
{
35+
"item.minecraft.stick": "Stick",
36+
"item.minecraft.diamond": "Diamond",
37+
}
38+
),
39+
lang="en_us",
40+
default_i18n=None,
41+
enabled=True,
42+
lang_props=LangProps(),
43+
)
44+
45+
texture_ctx = TextureContext(
46+
textures=defaultdict(dict),
47+
allowed_missing_textures={
48+
ResourceLocation("minecraft", "*"),
49+
},
50+
)
51+
52+
context: ContextSource = {}
53+
for ctx in [
54+
props,
55+
pm,
56+
loader,
57+
i18n,
58+
texture_ctx,
59+
]:
60+
ctx.add_to_context(context)
61+
62+
return context
63+
64+
65+
def test_shapeless(context: dict[str, Any]):
66+
data = {
67+
"type": "minecraft:crafting_shapeless",
68+
"ingredients": [{"item": "minecraft:stick"}],
69+
"result": {"item": "minecraft:diamond"},
70+
# for hexdoc
71+
"id": ResourceLocation("a", "b"),
72+
"resource_dir": PathResourceDir.model_construct(path=Path()),
73+
}
74+
75+
recipe = TypeAdapter(Recipe).validate_python(data, context=context)
76+
77+
assert isinstance(recipe, CraftingShapelessRecipe)
78+
79+
80+
def test_fabric_load_conditions(context: dict[str, Any]):
81+
data = {
82+
"type": "minecraft:crafting_shapeless",
83+
"ingredients": [{"item": "minecraft:stick"}],
84+
"result": {"item": "minecraft:diamond"},
85+
"fabric:load_conditions": [
86+
{
87+
"condition": "fabric:all_mods_loaded",
88+
"values": ["fabric-resource-conditions-api-v1"],
89+
}
90+
],
91+
# for hexdoc
92+
"id": ResourceLocation("a", "b"),
93+
"resource_dir": PathResourceDir.model_construct(path=Path()),
94+
}
95+
96+
recipe = TypeAdapter(Recipe).validate_python(data, context=context)
97+
98+
assert isinstance(recipe, CraftingShapelessRecipe)

0 commit comments

Comments
 (0)