Skip to content

Commit d0855e8

Browse files
committed
feat: generate resource pack overlays
- add dependency pillow
1 parent 66a5e58 commit d0855e8

File tree

23 files changed

+435
-5
lines changed

23 files changed

+435
-5
lines changed

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## TODO:
2-
- generate resource pack overlays
32
- add worldgen support
43
- merge nested overlays (overlays in the target pack)
54
- create more tests
5+
- allow separate dp and rp default formats

beet_observer/resource_pack.py

Lines changed: 149 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,151 @@
1-
from beet import Context
1+
from typing import Any
22

3+
from beet import Context, NamespaceProxy
34

4-
def gen_rp_overlays(ctx: Context, ctx_overlay: Context, directory: str):
5-
return
5+
6+
def gen_rp_overlays(ctx: Context, ctx_overlay: Context, overlay_dir: str) -> None:
7+
"""
8+
Generates overlays between two resource packs.
9+
10+
Keyword arguments:</br>
11+
`ctx` -- the build context</br>
12+
`ctx_overlay` -- the overlay context</br>
13+
`overlay_dir` -- the directory of the overlay</br>
14+
"""
15+
# create list of all resource pack file types
16+
file_types: list[tuple[NamespaceProxy[Any], NamespaceProxy[Any]]] = [
17+
(ctx.assets.blockstates, ctx_overlay.assets.blockstates),
18+
(ctx.assets.models, ctx_overlay.assets.models),
19+
(ctx.assets.languages, ctx_overlay.assets.languages),
20+
(ctx.assets.fonts, ctx_overlay.assets.fonts),
21+
(ctx.assets.glyph_sizes, ctx_overlay.assets.glyph_sizes),
22+
(ctx.assets.true_type_fonts, ctx_overlay.assets.true_type_fonts),
23+
(ctx.assets.shader_posts, ctx_overlay.assets.shader_posts),
24+
(ctx.assets.shaders, ctx_overlay.assets.shaders),
25+
(ctx.assets.fragment_shaders, ctx_overlay.assets.fragment_shaders),
26+
(ctx.assets.vertex_shaders, ctx_overlay.assets.vertex_shaders),
27+
(ctx.assets.glsl_shaders, ctx_overlay.assets.glsl_shaders),
28+
(ctx.assets.texts, ctx_overlay.assets.texts),
29+
(ctx.assets.textures_mcmeta, ctx_overlay.assets.textures_mcmeta),
30+
(ctx.assets.textures, ctx_overlay.assets.textures),
31+
(ctx.assets.sounds, ctx_overlay.assets.sounds),
32+
(ctx.assets.particles, ctx_overlay.assets.particles),
33+
(ctx.assets.atlases, ctx_overlay.assets.atlases),
34+
]
35+
# for each file type, check for required overlays
36+
for registry, registry_overlay in file_types:
37+
check_registry(ctx, ctx_overlay, overlay_dir, registry, registry_overlay)
38+
39+
# get pack.mcmeta overlay entries
40+
mcmeta: dict[str, dict[str, list[dict[str, Any]]]] = ctx.assets.mcmeta.data.copy()
41+
if "overlays" not in mcmeta:
42+
mcmeta["overlays"] = {}
43+
if "entries" not in mcmeta["overlays"]:
44+
mcmeta["overlays"]["entries"] = []
45+
entries = mcmeta["overlays"]["entries"]
46+
47+
# add overlays to pack.mcmeta
48+
for overlay in ctx.assets.overlays:
49+
# check if it's the top-level overlay
50+
if overlay == ctx.meta["observer"]["default_dir_rp"]:
51+
# delete pack.mcmeta from overlay (required for tests)
52+
default_dir = ctx.meta["observer"]["default_dir_rp"]
53+
if ctx.assets.overlays[default_dir].mcmeta:
54+
del ctx.assets.overlays[default_dir].mcmeta
55+
56+
# get pack format from build context
57+
if "default_format" in ctx.meta["observer"]:
58+
formats = ctx.meta["observer"]["default_format"]
59+
else:
60+
formats = ctx.assets.mcmeta.data["pack"]["pack_format"]
61+
else:
62+
# get formats from overlay pack
63+
if "supported_formats" in ctx_overlay.assets.mcmeta.data["pack"]:
64+
formats = ctx_overlay.assets.mcmeta.data["pack"]["supported_formats"]
65+
else:
66+
formats = ctx_overlay.assets.mcmeta.data["pack"]["pack_format"]
67+
68+
# update pack.mcmeta overlay entries
69+
entries.append(
70+
{
71+
"formats": formats,
72+
"directory": overlay,
73+
}
74+
)
75+
76+
# save overlay entries in pack.mcmeta
77+
if len(entries) > 0:
78+
ctx.assets.mcmeta.data.update({"overlays": {"entries": entries}})
79+
80+
81+
def check_registry(
82+
ctx: Context,
83+
ctx_overlay: Context,
84+
overlay_dir: str,
85+
registry: NamespaceProxy[Any],
86+
registry_overlay: NamespaceProxy[Any],
87+
) -> None:
88+
"""
89+
Generates overlays for each namespace proxy.
90+
91+
Keyword arguments:</br>
92+
`ctx` -- the build context</br>
93+
`ctx_overlay` -- the overlay context</br>
94+
`overlay_dir` -- the directory of the overlay</br>
95+
`registry` -- the namespace proxy from the build context</br>
96+
`registry_overlay` -- the namespace proxy from the overlay context</br>
97+
"""
98+
# check each file in the build pack
99+
for name in list(registry):
100+
if name in registry_overlay:
101+
# exists in both, so check if an overlay is needed
102+
gen_registry_overlay(ctx, overlay_dir, name, registry, registry_overlay)
103+
else:
104+
# exists only in overlay, so create a deletion overlay
105+
gen_registry_overlay(
106+
ctx, overlay_dir, name, registry, registry_overlay, "deletion"
107+
)
108+
109+
# for all remaining files (of this type) in the overlay pack, add to build pack as an overlay
110+
for name in list(registry_overlay):
111+
gen_registry_overlay(
112+
ctx, overlay_dir, name, registry, registry_overlay, "addition"
113+
)
114+
115+
116+
def gen_registry_overlay(
117+
ctx: Context,
118+
overlay_dir: str,
119+
name: str,
120+
registry: NamespaceProxy[Any],
121+
registry_overlay: NamespaceProxy[Any],
122+
type: str = "",
123+
) -> None:
124+
"""
125+
Checks if two functions have the same contents and generate an overlay if they don't.
126+
127+
Keyword arguments:</br>
128+
`ctx` -- the build context</br>
129+
`overlay_dir` -- the directory of the generated overlay</br>
130+
`name` -- the name of the file</br>
131+
`registry` -- the namespace proxy from the build context</br>
132+
`registry_overlay` -- the namespace proxy from the overlay context</br>
133+
`type` -- either "deletion" or "addition" (default: `""`)</br>
134+
"""
135+
if type == "deletion":
136+
# move file from build pack to overlay in build pack
137+
default_dir = ctx.meta["observer"]["default_dir_rp"]
138+
ctx.assets.overlays[default_dir][name] = registry[name]
139+
del registry[name]
140+
elif type == "addition":
141+
# move function from overlay pack to overlay in build pack
142+
ctx.assets.overlays[overlay_dir][name] = registry_overlay[name]
143+
else:
144+
# check if files are exactly the same
145+
if registry[name] != registry_overlay[name]:
146+
# move function from overlay pack to overlay in build pack
147+
ctx.assets.overlays[overlay_dir][name] = registry_overlay[name]
148+
149+
# remove file from overlay pack
150+
if name in registry_overlay:
151+
del registry_overlay[name]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
resource_pack:
2+
load: src
3+
pack_format: 42
4+
supported_formats: [34,42]
5+
6+
pipeline:
7+
- beet_observer
8+
9+
meta:
10+
observer:
11+
overlays:
12+
- process: proc
814 Bytes
Loading
669 Bytes
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"pack": {
3+
"pack_format": 34,
4+
"description": ""
5+
}
6+
}
669 Bytes
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
resource_pack:
2+
load: src
3+
pack_format: 42
4+
supported_formats: [34,42]
5+
6+
pipeline:
7+
- beet_observer
8+
9+
meta:
10+
observer:
11+
default_format: 42
12+
overlays:
13+
- process: proc
669 Bytes
Loading
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"pack": {
3+
"pack_format": 34,
4+
"description": ""
5+
}
6+
}

0 commit comments

Comments
 (0)